Ship Astro to Cloudflare Pages
GitHub repo in, live site out. Auto-deploy on every push, HTTPS included, zero dollars a month. You'll talk to Claude Code for the code bits and click through Cloudflare's dashboard for the rest.
Contents
📋 What You Need
✅ Prerequisites
- An Astro project (new or existing) on your machine
- A free GitHub account — github.com/signup
- A free Cloudflare account — dash.cloudflare.com/sign-up
- Claude Code installed locally (we're using prompts, not terminal commands)
💡 Good to Know
- Cloudflare Pages free tier: unlimited bandwidth, 500 builds/month, 100 custom domains
- HTTPS is automatic. No cert wrangling.
- Global CDN out of the box — your site is fast everywhere by default
Spin up a fresh Astro project in this folder using the minimal starter.
Use npm, skip the TypeScript strict prompt, and initialize git.
📦 Step 1: Push Your Astro Project to GitHub
Cloudflare Pages deploys from a Git repo. Your project needs to live on GitHub first.
Ask Claude Code
Open Claude Code inside your Astro project folder and send this prompt:
Create a new GitHub repo called my-astro-site under my account,
push this project to it on the main branch, and make the repo public.
Use the GitHub CLI if it's installed, otherwise walk me through it.
Claude Code will handle git init, the first commit, creating the remote repo, and pushing. If you'd rather do it by hand, create the repo at github.com/new and push your existing code to it.
github.com/your-username/my-astro-site in a browser and see your Astro files listed.
🟧 Step 2: Create a Cloudflare Pages Project
This part is click-through in the Cloudflare dashboard. No prompts, just a browser.
- Log into dash.cloudflare.com
- In the left sidebar, click Workers & Pages
- Click the Create button (top right)
- Choose the Pages tab
- Click Connect to Git
🔗 Step 3: Connect Your GitHub Repo
After authorizing GitHub, Cloudflare shows a list of repos you can deploy:
- Find
my-astro-sitein the list - Click Begin setup
- On the next screen, the Project name auto-fills from the repo — this becomes your
<name>.pages.devsubdomain. Change it if you want a different URL. - Leave Production branch as
main
⚙️ Step 4: Configure the Build
Still on the same dashboard screen, scroll down to Build settings. Fill these in:
| Field | Value |
|---|---|
| Framework preset | Astro |
| Build command | npm run build |
| Build output directory | dist |
| Root directory | (leave empty unless your Astro app lives in a subfolder) |
| Environment variables | Add NODE_VERSION = your local Node version (e.g. 20) |
Picking the Astro preset auto-fills most of this. The one thing worth double-checking is NODE_VERSION — Cloudflare defaults to an older Node, and Astro 6+ needs 18.20+ or 20+.
Add a .node-version file with the current Node version,
commit it, and push. That way Cloudflare reads the version
from the repo and I don't need the env var.
🚀 Step 5: First Deploy
Click Save and Deploy. Cloudflare clones your repo, runs npm install and npm run build, and ships the dist folder to its global edge network.
You'll see a live build log. A first deploy usually takes 1–2 minutes.
my-astro-site.pages.dev. Open it. That's your site, served from hundreds of cities simultaneously, with HTTPS, for $0.
🌐 Step 6: Add a Custom Domain
The .pages.dev URL works forever, but if you want yoursite.com:
- Inside your Pages project, click the Custom domains tab
- Click Set up a custom domain
- Enter your domain (e.g.
yoursite.com) - Cloudflare auto-adds a CNAME record if your domain's DNS is already on Cloudflare
- If your domain lives elsewhere, Cloudflare shows you the CNAME to add at your registrar
Once DNS propagates (seconds to minutes if on Cloudflare, up to 24 hours elsewhere), HTTPS is issued automatically.
Domain not on Cloudflare yet?
Moving it in is free and takes ~5 minutes:
- Dashboard → Add a site → enter your domain → pick the free plan
- Cloudflare imports your DNS records
- Update your registrar's nameservers to the two Cloudflare gives you
- Done — now the Pages CNAME is automatic
🔄 Step 7: Auto-Deploy on Every Push
This part is already done — the GitHub connection you set up earlier is the auto-deploy. Every push to main triggers a new production build. Every push to another branch spins up a preview URL.
To ship a change, ask Claude Code:
Commit the current changes with message "Update homepage copy"
and push to main.
Cloudflare picks up the push within seconds and starts building.
Preview deploys
Branches other than main get their own preview URL (branch-name.my-astro-site.pages.dev). Perfect for showing work-in-progress without touching production.
Create a branch called feature/new-hero, commit the current
changes on it, and push. I want the preview URL Cloudflare
generates for it.
🔍 Troubleshooting
Build fails: "Cannot find module" / Node version mismatch
Cloudflare is using a different Node version than you are locally.
Check what Node version I'm running locally, then pin it
in the repo by creating a .node-version file with that
version and pushing.
Or add NODE_VERSION as an environment variable in Settings → Environment variables.
Build succeeds but the site is blank
Output directory is wrong. Astro builds to dist by default, not build or public. Check Settings → Builds & deployments → Build configurations.
404 on every route except the homepage
You probably have SSR config mismatched with a static deploy. For a pure static Astro site, your astro.config.mjs should not set output: 'server'. If you want SSR, use the Cloudflare adapter: npm install @astrojs/cloudflare and set adapter: cloudflare().
Custom domain stuck on "Verifying"
DNS hasn't propagated yet. If your domain isn't on Cloudflare, it can take up to 24 hours. If it is on Cloudflare, usually under a minute — try a hard refresh of the dashboard.
Push isn't triggering a deploy
Check Settings → Builds & deployments → Branch deployments. Make sure the production branch matches the branch you're actually pushing to (usually main, sometimes master).
🎯 Next Steps
⚡ Speed tune
Cloudflare Pages serves from the edge by default. For dynamic bits, add Workers for API routes — still free up to 100k requests/day.
🔒 Environments
Use preview deploys as a staging environment. Set different env vars for Production vs Preview under Settings.
📈 Analytics
Built-in, privacy-first, no cookie banner. Toggle it on under Analytics in your project.
The bill
GitHub: $0. Cloudflare Pages: $0. HTTPS cert: $0. Global CDN: $0. Auto-deploy pipeline: $0. The only thing you pay for is the domain — and only if you want a custom one.