MW
Tutorial

Deploy an Astro site to Cloudflare Pages

From `git init` to a live URL on a custom domain in under 30 minutes. Covers Pages config, custom domains, and the most common build errors.

beginner 30 min May 12, 2026
An Astro project (any starter works) A GitHub account A Cloudflare account (free tier is fine)

DEPLOY AN ASTRO SITE TO CLOUDFLARE…

Cloudflare Pages is the path of least resistance for shipping an Astro site to production. This walkthrough takes you from local repo to a live custom-domain URL in five steps.

1. Push your project to GitHub

If your Astro project isn’t on GitHub yet:

cd your-astro-project
git init
git add .
git commit -m "Initial commit"
gh repo create your-astro-project --public --source=. --push

(If you don’t have gh installed, create the repo manually on github.com and push to it.)

2. Create a Pages project

In the Cloudflare dashboard:

  1. Workers & Pages → Create application → Pages → Connect to Git
  2. Pick your repo
  3. Framework preset: Astro (Cloudflare detects this automatically)
  4. Build command: npm run build
  5. Build output directory: dist

Click Save and Deploy. The first build takes 1-3 minutes.

3. Add a custom domain

Once the first build succeeds you’ll have a your-project.pages.dev URL. To use your own domain:

  1. Project → Custom domains → Set up a custom domain
  2. Enter your-domain.com
  3. Cloudflare auto-creates the DNS records if the domain is on Cloudflare DNS. If it isn’t, follow the displayed CNAME instructions.

DNS propagation is usually instant on Cloudflare-managed domains.

4. Set environment variables (optional)

If your Astro project uses import.meta.env.X, add the same X under Project → Settings → Environment variables → Production. You’ll need to trigger a new deploy after adding env vars for them to take effect.

5. Enable auto-deploy on push

Already done — connecting a GitHub repo enables it automatically. Every push to main triggers a new production deploy; every push to other branches creates a preview deploy at <branch>.your-project.pages.dev.

Verification

Open your-domain.com in an incognito window. Your site should load. Check the page source — it should be static HTML (not a JS placeholder). Network tab → first byte should be ~30-80ms from most locations.

Common errors

ErrorCauseFix
Build fails on npm installLockfile / Node version mismatchSet NODE_VERSION=20 in env vars
404 on every pageWrong output directoryConfirm it’s dist, not build or public
Images return 404Forgot to import as ?urlUse Astro’s getImage() or Image component
Custom domain stuck on “Verifying”DNS not on CloudflareAdd the CNAME manually at your DNS host

What’s next

You've completed this tutorial!

Get the next one in your inbox. Practical tips, no fluff.

Subscribe

Get weekly notes in your inbox

Practical tips, tutorials and resources. No spam.