Cloudflare for a Static Website: One Map Across DNS, SSL, Pages, and Workers

By Simeon Matheka, Founder & Creative Director · Published 2026-08-26 · Updated 2026-09-07 · 12 min read

Put a static marketing site on Cloudflare in order: zone and proxy, Universal SSL, Pages or Workers static assets, the real domain, then _redirects and _headers. What to skip if the site is only HTML, CSS, and JavaScript.

Still-life of a cream paper map on a walnut table with a rust-red string linking pins labeled DNS, SSL, Files, and Domain

You have HTML, CSS, and JavaScript, maybe a Single Page Application (SPA). You want it on the real domain with HTTPS, without a PHP origin. On Cloudflare that is six jobs in a row: the zone, Domain Name System (DNS) proxy status, Transport Layer Security (TLS), where the files live, the hostname, then redirects and headers.

Start in the wrong product and you get a padlock on workers.dev with a blank custom domain, or email that dies because mail.example.com was proxied with the website. The table below is the order we use on static client sites. If the dist folder is still on your laptop, host it first: how to host a static website on Cloudflare.

The map, in order

Do these in this sequence. Skipping ahead is how you get a green SSL padlock on workers.dev and a blank custom domain.

StepJobOfficial homeSkip if
1. ZoneNameservers on Cloudflare so you own DNS and certificatesAdd a site / DNSYou cannot move nameservers (then Pages still has an option Workers does not)
2. ProxyOrange-cloud the website. Grey-cloud mail, FTP, SSHDNS proxy statusThe hostname is not HTTP
3. TLSLet Universal SSL cover proxied hostnamesUniversal SSLYou need a cert before the zone is active (then Advanced / Custom)
4. FilesPut the build output on Pages or Workers static assetsPages, or Workers static assetsYou are still on a PHP origin you intend to keep
5. DomainAttach the real hostname. Redirect www or apexCustom domainsYou only need a preview URL
6. Traffic rules_redirects and _headers in the asset folderPages redirects / headers (Workers supports the same files)You have zero legacy URLs and default headers are enough

Zone and proxy: the website is HTTP, mail is not

If Cloudflare does not manage the zone’s nameservers, you are on a partial setup. Universal SSL and Custom Domains behave differently there. For a client site we control, we put the zone on Cloudflare first. Then proxy status is a protocol decision, not a taste decision.

  • Website hostnames (apex, www, and the Pages or Workers target): Proxied. That is how you get the content delivery network (CDN), the Web Application Firewall (WAF), and Universal SSL on those names.
  • Mail hostname, FTP, SSH: DNS only. Cloudflare’s HTTP proxy does not carry those protocols.

If cPanel webmail works and Outlook does not, the mail hostname is still proxied. Set mail to DNS only. Do not grey-cloud the website to make Outlook work.

Universal SSL is not a plugin

On a full setup, Cloudflare issues and renews a Domain Validated (DV) Universal SSL certificate that covers the apex and first-level subdomains (example.com and www.example.com). It applies to proxied hostnames. Grey-cloud a name and you are back to whatever certificate lives on the origin. See Universal SSL.

Deeper subdomains (app.staging.example.com) are outside that free cover on a full setup. Use Total TLS or advanced certificates if you actually need them. Most static marketing sites do not.

If you need a certificate before the zone is active on Cloudflare, Universal SSL will not be there yet. That is the Advanced or Custom certificate path, not a reason to skip the zone cutover.

Where the files live: Pages vs Workers static assets

This is the fork Cloudflare made messy on purpose. The Pages overview now asks if you are sure you want Pages, and tells you to start new projects on Workers. Workers static assets is the replacement for “upload HTML and cache it globally.” Requests for those assets are still not billed like Worker CPU. You are not buying Durable Objects by deploying a dist folder.

This site is a Vite React SPA. The production config is a Worker with an assets directory and no Worker script. not_found_handling is 404-page, so unknown paths return a real 404 instead of index.html. A Single Page Application (SPA) fallback looks convenient and trains Google to treat junk URLs as thin pages. Set the knob yourself. Pages used to guess from whether it saw index.html and 404.html. Guessing is how SPAs silently break.

NeedPages todayWorkers static assets
New static or SPA marketing siteWorks, but Cloudflare points you at WorkersDefault for new work
Existing Pages project, no painLeave it. Rollbacks, redirects, headers already workMigrate only for a feature Pages cannot give you
Custom domain on a zone Cloudflare does not nameserverSupportedNot supported. Custom Domains require a Cloudflare zone you own
SPA fallbackInferred from filesSet not_found_handling yourself
_headers and _redirectsNative if the files are in the asset outputSame, if they land in the assets directory
File-based Pages Functions folderNativeCompile or replace. Not a reason to pick Pages for a static site

The Pages to Workers migration guide is a compatibility matrix, not a mandate. Read it when you have a Pages Function, a custom branch alias you rely on, or a domain outside Cloudflare DNS. Do not read it as “every static site must move this week.”

Domain: workers.dev is not the website

Pages gave you a pages.dev URL. Workers gives you workers.dev if you opt in. Both are fine for QA. Clients do not launch on them. Attach a Custom Domain so Cloudflare writes the DNS record and the certificate for that hostname. Custom Domains are exact-match. They do not include www for free if you attached the apex, or the apex if you attached www.

To serve both:

  1. Attach the hostname you want as canonical (usually the apex, or www if that is the brand).
  2. Add a Redirect Rule from the other hostname to the canonical one.
  3. Keep a proxied DNS record on the hostname you redirect from. Originless placeholders are A 192.0.2.0 or AAAA 100::. Traffic never reaches those addresses because the record is proxied.

Routes (example.com/*) are for “run this Worker on some paths, leave the rest on an origin.” A static site that is the origin should use a Custom Domain, not a leftover CNAME to 100:: plus a wildcard route. If you still have that pattern, the custom domains doc is the migration, not a new product.

_redirects and _headers belong in the build output

For a static site these two files replace half of “I need a Worker.” Put them in public/ (or static/) so the bundler copies them into dist. Cloudflare parses _redirects from the asset directory on Pages, and Workers static assets do the same. Redirects run before headers. First matching line wins. Static rules above dynamic ones. Default status is 302. Use 301 when the move is permanent.

Limits that matter on a real cutover: 2,000 static redirects and 100 dynamic ones per file. Past that, Bulk Redirects sit in front. Query-string matching and country-based redirects are not in _redirects. Do not invent them there.

Headers are how a static SPA sets Content-Security-Policy, long cache on hashed /assets/*, and shorter cache on HTML. If the file never reaches the assets directory, Cloudflare never sees it. That is the usual “I added _headers but production ignores it” bug.

Cache after deploy is not a mystery setting

Static assets on Workers are cached on the network. First request fills the nearest cache. Later misses can be filled from a nearby tier, not from your Git repo. Hashed filenames in /assets/* can be cached for a year. index.html should not. If a cover image or Open Graph file reused the same URL, scrapers will keep the old bytes until purge or TTL. Change the filename when the art changes, or purge that prefix. Do not orange-cloud a different hostname hoping that resets cache.

Preview URLs and rollbacks are the day-to-day controls. The maintenance blueprint covers uptime, Core Web Vitals, and watching the money paths after launch. At cutover, treat production as a deployment you can roll back, not an FTP folder you overwrite.

What this static site does not need

You do not need the rest of the Workers platform to ship a homepage. Leave these until a real job appears:

  • D1, Durable Objects, KV as a CMS, Vectorize, Hyperdrive: you already have a headless store or you do not need one.
  • Workers AI, Browser Run, Workflows, Queues: app platform. Not the homepage.
  • Cron Triggers: useful later for IndexNow or a health ping. Not a launch blocker.
  • Pages Functions file routing: if you need a server path, write a small Worker or keep the form off-origin. See dynamic forms on the edge.

When the zone, proxy, TLS, files, domain, and traffic files are in place, the static site is live. That sequence is part of how we ship websites. If a live domain is stuck between cPanel and the edge, get in touch.

Frequently asked questions

Should a new static site use Cloudflare Pages or Workers?

For a new project in 2026, start on Workers with static assets. Cloudflare’s own Pages overview now tells you Workers is the primary platform. A marketing Single Page Application (SPA) or pre-rendered HTML folder does not need Durable Objects or a database on Cloudflare. If a Pages project already serves production traffic, do not migrate for sport.

Do I need a Worker script if the site is only HTML, CSS, and JavaScript?

No. Workers can ship an assets directory with no `main` script. You still get global cache and a custom domain. Add a Worker script later if you need an API path, authentication in front of files, or HTML rewriting.

Why does the apex work but www does not (or the reverse)?

A Custom Domain matches one hostname exactly. example.com and www.example.com are two attachments, or one attachment plus a redirect rule. You also need a proxied Domain Name System (DNS) record on the hostname you redirect from. Dummy A 192.0.2.0 (or AAAA 100::) is the usual originless placeholder.

Can the website sit on Cloudflare while email stays on cPanel?

Yes. Proxy the website hostnames. Set the mail hostname to DNS only. Mail Exchanger (MX) records cannot be proxied. Webmail can stay orange because it is HTTPS.

Where do contact forms go if the site is static?

The HTML is static. The POST is not. Validate at the edge or a backend, store the row, then notify Slack or email asynchronously. Our forms article covers Supabase and edge functions. Do not bolt a PHP mailer onto a static deploy.

Tags: Cloudflare, Cloudflare Pages, Cloudflare Workers, static site, DNS, SSL, custom domains, edge hosting