The easy way
Do not follow a tutorial; the interface changes faster than any page about it. Have an AI coding agent walk you through, and let it do the deploying.
- Create a free Cloudflare account at cloudflare.com. That is the one thing only you can do.
- Make an API token so the agent can publish on your behalf: in the dashboard, My profile → API tokens → Create token. Use the Edit Cloudflare Workers template, which covers Pages, and if your domain is on Cloudflare add Zone → DNS → Edit for it. Copy the token once; it is shown once.
- Open the site folder in your agent — Claude Code, Codex, Gemini CLI, Cursor, or whichever you use — and give it the token and your account ID (on the right of the dashboard's overview page).
- Tell it what you want, in plain language:
Publish this folder to Cloudflare Pages as a new project. Connect my domain. If there is a contact form, set up the email key so submissions reach me at [your address], and send a test.
Then check the test arrived, and delete the token if you do not plan to redeploy soon; you can always make another.
The full guide
Step by step, if you would rather do it by hand or want to know what the agent is doing.
1. The account
Sign up at cloudflare.com with the email you want the site tied to. The free plan is all this needs: Pages, custom domains, the contact-form function and a generous allowance of visitors are included. You do not need to add a payment method to publish.
2. The project
In the dashboard go to Workers & Pages → Create → Pages. You have two routes:
- Upload the folder. Upload assets, name the project (lowercase, hyphens), drag the site folder in, Deploy. Thirty seconds later it is live at
<project>.pages.dev. Updating later means uploading the folder again. - Connect a Git repository. If the folder lives in GitHub or GitLab, connect it and every push publishes. Leave the build command empty — the folder is already built — and set the output directory to the folder that holds
index.html.
Upload is the simpler route and the one most teams should take.
3. Your domain
In the project, Custom domains → Set up a custom domain, type it, continue. If the domain's DNS is already on Cloudflare, the record is added for you and the certificate follows within minutes. If the domain is registered elsewhere, either move its nameservers to Cloudflare (recommended, free) or add the CNAME the dialog shows at your registrar. Both yourdomain.com and www. can be added; make one redirect to the other under Rules → Redirect rules.
4. The contact form
A static page cannot send email by itself. What ships in the folder is a functions/ directory holding one small script; Cloudflare runs it alongside the site as a Pages Function, and the form posts to it. It needs one secret — a key for an email-sending service. We use Resend, whose free tier is enough:
- Create an account at resend.com, verify the domain you will send from (it walks you through two DNS records), and create an API key.
- In your Pages project, Settings → Variables and secrets, add it under the name the script expects — it is written at the top of the script — as a secret, not a plain variable.
- Set the destination address the same way if the script asks for one.
- Redeploy once so the function picks the values up.
The key lives in the project's settings and nowhere else. Anything that is in the page itself is public.
5. The test
Open the live site, fill the form, send. The message must arrive in your inbox — not "the page said thanks". The most common launch-day failure is a form that reports success and posts into nowhere, and the only way to know is to send one to yourself.
6. Updating the site later
The folder is the site. Edit it — or have an agent edit it — and upload it again (or push, if you connected a repository). Every deployment is kept, and any earlier one can be rolled back to from the project's Deployments list.
7. If something is wrong
Pages has a Deployments view with a log per deployment, and the function has a real-time log under Functions. Paste whatever it says into your agent; that is usually enough. The three things that go wrong: the wrong folder was uploaded (no index.html at its root), the domain's DNS has not propagated yet (give it an hour), or the email key is missing or misnamed (the function log says so).