MossBySea

How to deploy Astro on Cloudflare Pages

Guide October 21, 2026

Built 2026-09-22
Stack Astro 5 static build · Cloudflare Pages · Cloudflare Registrar + DNS · GitHub
Total cost $10.46/year, all in

mossbysea runs on Astro 5, built static, pushed to GitHub, and served from Cloudflare Pages. This is the walkthrough I wish I’d had before the first push — the parts that are one checkbox in the dashboard and the one setting that silently breaks the build if you skip it.

If your site is already live and something went wrong after deploy, that’s a different article: eight things that broke on Cloudflare Pages. This one stops at “it’s on a real domain.”

What you need before you start

  • An Astro project with a working local build (npm run build succeeds, output lands in dist).
  • A GitHub repository with that project. Cloudflare Pages pulls from GitHub directly; you don’t run any deploy command yourself.
  • A Cloudflare account (free tier is enough) and, later, a domain in Cloudflare Registrar or transferred in.

That’s it. No server, no container, no database.

Step 1 — Create the Pages project

In the Cloudflare dashboard: Workers & Pages → Create → Pages → Connect to Git. Authorize GitHub, pick the repo, and Cloudflare offers a framework preset. Choose Astro.

The preset fills in two fields for you:

  • Build command: npm run build
  • Build output directory: dist

Don’t change them unless your project is non-standard. Astro’s default static output already goes to dist, so the preset is correct out of the box.

Step 2 — Set the Node version (the gotcha)

This is the one setting that bites people. Cloudflare Pages builds on a default Node version that can be older than what Astro 5 needs. Astro 5 requires Node 18.17.1, 20.3.0, or 22+. If the build container runs an older Node, npm run build fails with a cryptic engine error and the deploy shows as failed before it even runs your code.

Two ways to pin it:

  1. In the dashboard: Settings → Builds & deployments → Build configuration → Node.js version and set it to 22 (or 20).
  2. Or add it to package.json so it travels with the repo:
{
  "engines": {
    "node": ">=20.3.0"
  }
}

Do one of these before the first build. I set it in the dashboard and forgot it existed — the build failed once, the error pointed at Astro’s engine check, and the fix was this single dropdown.

Step 3 — Push and watch the first deploy

Commit and push to the branch you connected (I use main). Cloudflare picks it up automatically, runs the build, and gives you a *.pages.dev URL when it’s green.

Open that URL. It’s a real, public, HTTPS URL — your site is live before you’ve touched DNS. This is also the moment to click through every page, because the pages.dev URL serves the exact build that will later sit on your domain.

Step 4 — Connect the custom domain

Back in the Pages project: Custom domains → Set up a domain. Enter it, and Cloudflare tells you which DNS records to add (usually a CNAME to the pages.dev host, or it manages the record for you if the domain is already in Cloudflare).

Two things worth knowing here:

  • Don’t disable the workers.dev subdomain yet. It’s tempting to clean it up, but a CNAME or a setting can still point at it — and turning it off takes the thing your www depends on down with it. That specific failure has its own write-up: Cloudflare Pages www down: fix Error 1016.
  • HTTPS is automatic. Cloudflare issues and renews the certificate; you don’t install one.

Step 5 — Confirm the loop

Make a small edit, push, and watch it appear on the custom domain within a minute or two. That push-to-live loop is the whole point: write, commit, it’s published. No build server to babysit, no FTP.

What this costs

With the domain in Cloudflare Registrar and DNS, Email Routing, and Pages all on the free tier, the only line item is the domain itself — about $10.46/year for the .com. Hosting, SSL, and email forwarding are included. That’s the entire bill for a live, HTTPS, custom-domain site.

Where to go next

The deploy is the easy part. The interesting failures show up after you’re live, and they deserve their own pages:

Everything else — the dashboard move, the dead URL after a green build, the browser-cache false alarm, the new-domain delay — is collected in eight things that broke on Cloudflare Pages. Read that before you congratulate yourself.