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:
- Workers & Pages → Create application → Pages → Connect to Git
- Pick your repo
- Framework preset: Astro (Cloudflare detects this automatically)
- Build command:
npm run build - 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:
- Project → Custom domains → Set up a custom domain
- Enter
your-domain.com - 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
| Error | Cause | Fix |
|---|---|---|
Build fails on npm install | Lockfile / Node version mismatch | Set NODE_VERSION=20 in env vars |
| 404 on every page | Wrong output directory | Confirm it’s dist, not build or public |
| Images return 404 | Forgot to import as ?url | Use Astro’s getImage() or Image component |
| Custom domain stuck on “Verifying” | DNS not on Cloudflare | Add the CNAME manually at your DNS host |
What’s next
- Add a sitemap + RSS (both Astro integrations).
- Build a headless WordPress source if you want a CMS.
- Cache API responses at the edge using the KV cache snippet.
Get the next one in your inbox. Practical tips, no fluff.
More tutorials
View all-
Block Patterns
Register reusable block compositions — landing-page hero, feature grid, FAQ section — that users insert as a complete unit.
25 min
-
Block Attributes and Serialization
Master the attribute system — types, sources, defaults, and how block data round-trips between the editor, the database, and the front-end.
30 min
-
Building a Block Plugin
Package your block as a proper WordPress plugin — file structure, asset enqueueing, server-side render callbacks, plugin metadata.
35 min