Host a Free Website with Cloudflare Pages and GitHub
Cloudflare Pages hosts a static site for free, straight from a GitHub repo.
Connect the repo and every push triggers a build — jekyll build, hugo,
whatever your generator runs — served from Cloudflare’s global edge in about a
minute. The repo is your source of truth, and push is deploy: edit, commit,
push, and the live site updates itself. No server, no monthly bill.
This is the same setup this very site runs on. Building it is the guide.
What you’ll need: a GitHub account with your site in a repo, and a free Cloudflare account. Setup takes about 15 minutes, once.
1. Put your site in a GitHub repo
Get your site into a GitHub repo. For a plain site, that’s the folder with your
index.html; for a static-site generator, it’s the whole project — the
source, not the built output. Cloudflare runs the build.
(New to Git? GitHub’s “Create a repo” guide covers the first push.)
2. Create a Pages project
In the Cloudflare dashboard, pick your account, then open Workers & Pages (under Compute) and hit Create application. Cloudflare now leads with its Workers flow — click “Looking to deploy Pages? Get started,” then Import an existing Git repository. Authorize the GitHub app, and when it offers, scope it to just the repo you’re deploying, not every repo you own. Pick your repo.
3. Tell Cloudflare how to build it
Cloudflare needs two things: the build command, and where the output lands.
- Plain HTML? Preset None, no build command, output directory = the folder holding your files (often the repo root).
- Static-site generator? Pick its preset (Jekyll, Hugo, Astro, …) to fill
in both — Jekyll builds with
jekyll buildinto_site.
Two things that trip people up:
- Runtime version. Set it with an environment variable so the builder matches
your local one:
RUBY_VERSION = 3.2.2for Jekyll,NODE_VERSIONfor JS tools. - Output directory must match reality. If your build writes to
distorpublic, set that here — or you’ll deploy an empty site.
4. Deploy
Hit Save and Deploy. Cloudflare clones the repo, runs the build, and
publishes — in about a minute you get a live URL at your-project.pages.dev, on
HTTPS and the global edge.
If the build fails, open the build log — it’s almost always a wrong output directory or a missing version variable from the last step. Fix it and push; Cloudflare retries on its own.
5. Put it on your own domain
pages.dev works, but you’ll want your own address. In the project’s Custom
domains tab, add your domain. If its DNS is already on Cloudflare, Cloudflare
wires up the record and issues the HTTPS certificate for you — usually live within
minutes.
6. From now on, it deploys itself
That’s the payoff: edit → commit → push, and Cloudflare rebuilds and
redeploys. Every push to main is a new deployment; other branches get their own
preview URLs, so you can look before you ship.
Next: keep it private if it’s not for everyone
A Pages site is public by default. To limit it to specific people — a staging site, an internal dashboard — put a free login wall in front and allow only the email addresses you choose. See the companion guide, Restrict a Website to Specific People with Cloudflare Access.