Deployment

How to Deploy a Static Site to Cloudflare Pages (Step by Step)

If you are paying for shared hosting to serve plain HTML, you are paying for a control panel you do not use and a bandwidth cap you have to think about. A static site on Cloudflare Pages costs nothing, serves from the edge, and deploys on every git push.

Here is the whole setup. It takes about five minutes the first time.

What you need first

  • A repository on GitHub or GitLab. Cloudflare builds from Git, so the code has to live somewhere it can reach.
  • A Cloudflare account. The free plan is enough — the free tier includes unlimited bandwidth and 500 builds per month.
  • Node.js 20.19.1+ or 22.12.0+ if you want to build locally before pushing.

That is it. No credit card, no server to patch.

Step 1 — Confirm the build output

Whatever framework you use, Cloudflare needs to know two things: the command that builds the site, and the folder that comes out the other end.

For Astro, that is npm run build producing dist/. Verify it locally first, because a build that fails on Cloudflare wastes a deployment cycle:

npm install
npm run build
# dist/index.html should now exist

If dist/index.html is there, you are ready to push.

Step 2 — Push, then connect the repository

git add .
git commit -m "ready for deploy"
git push origin main

Then in the Cloudflare dashboard: Workers & Pages → Create → Pages → Connect to Git, authorise GitHub, and pick the repository. Cloudflare pre-fills build settings when it recognises the framework. Confirm they match:

SettingValue
Framework presetAstro (or your framework)
Build commandnpm run build
Build output directorydist
Production branchmain

Every push to main now triggers a production deploy. Pull requests get their own preview URL automatically, which is genuinely useful for reviewing layout changes on a real device before they go live.

Step 3 — Point your domain at it

Add the domain under Custom domains. If the domain’s DNS is already on Cloudflare, it connects in seconds and the certificate is provisioned for you. If the DNS lives elsewhere, Cloudflare will give you nameservers to switch to, which takes a few hours to propagate.

Step 4 — The four settings that break things later

This is the part most guides skip, and it is where people lose money quietly.

1. Turn Rocket Loader off. Under Speed → Optimization. Rocket Loader rewrites how JavaScript loads on your pages. That is fine for a plain blog and fatal for ad scripts and analytics verification — the script simply never runs, and nothing in any dashboard tells you why.

2. Turn Bot Fight Mode off. It will challenge or block the automated crawlers that ad networks use to review your site and verify your traffic. The visible symptom is an application that “just never gets reviewed”.

3. Be careful with Auto Minify. Aggressive HTML minification can break inline scripts. If your ad units render blank after enabling it, this is the first thing to revert.

4. Do not add a Content-Security-Policy header yet. Ad network scripts load from a shifting list of third-party domains. A CSP that does not list every one of them will silently blank your ads. Add one only when you are ready to enumerate every domain.

What this costs

ItemCost
Cloudflare Pages (static)$0
Bandwidth$0 — unlimited on the free plan
Builds500/month free
SSL certificateAutomatic
Domain~$10/year at cost price

The only recurring cost is the domain. That is the whole bill.

When this is the wrong choice

Static hosting on Pages is the wrong call if you need server-side sessions, a database on the same origin, or anything that must run per-request without an edge runtime. You can add Workers for that, but at that point you are running an application, not a static site, and the deployment model deserves a separate decision.

For a content site — which is what most people actually need — static is faster, cheaper and has fewer moving parts. There is nothing to patch and nothing to restart.


Written by TestedHost. Every recommendation on this site comes from running the setup described, on a live deployment — not from a vendor spec sheet. Spotted something out of date? Tell us.