Publishing and Custom Domains
Publishing is two distinct steps: a build turns your content into static files, and a deploy uploads those files to Cloudflare Pages. This page covers what the build produces, how the deploy works, and how to put your own domain in front of it.
The build
Settings, Generation has the Build Site button. A build is a full production build: it cleans the output directory first and minifies the HTML it writes.
Every build produces:
- one directory per post at
posts/{slug}/index.html - one directory per page at
{slug}/index.html - the homepage at
index.html, either the post listing or a page you promoted - paginated archives at
posts/index.htmlandposts/page/{n}/index.html - a tag index at
tags/index.htmland a page per tag attags/{slug}/index.html - a
404.html, which static hosts serve for unknown routes - member pages (login, signup, verify, portal)
rss.xmlandatom.xml, plus/rss,/feed, and/atomdirectories that redirect to themsitemap.xmlandrobots.txt(whoseSitemap:line uses your Site URL)llms.txtandllms-full.txt- your theme’s static assets, your site’s own static files (which override theme files of the same name), and the site’s media library
Drafts are excluded unless you turn on “Include draft posts in build”. Paid-tier gated posts are redacted before anything is rendered, so a gated body never reaches the static output, the feeds, the sitemap, or llms.txt.
After a build the page shows a “Last built” timestamp and a Download button that gives you the entire output as a zip. That zip is a complete static site: you can host it anywhere, WordPuppi included or not.
Deploying to Cloudflare Pages
Connect Cloudflare Pages on the site’s Platforms page first (see Getting Started for the token permissions). Then Build & Deploy on the generation page does the whole thing in one press.
Build
The site is rebuilt from current content and the resolved theme, so a deploy never ships a stale build.
Ensure the project
WordPuppi looks up the Pages project by name, and creates it (production branch main) if it does not exist. The name defaults to your site slug, unless the connection or the request names one.
Upload
Every output file is hashed, and Cloudflare is asked which hashes it is missing. Only missing files are uploaded, in batches, with retries and automatic token refresh. _redirects and _headers travel as their own parts rather than as static assets.
Create the deployment
A manifest of path to hash is posted, and Cloudflare publishes the deployment. The URL comes back in the toast and stays linked on the card.
Unchanged files are not re-uploaded, so a second deploy of a mostly unchanged site is quick.
The generated _redirects
The build writes a Cloudflare Pages _redirects file with:
200rewrites for/member/verify/*and/member/unsubscribe/*, so member magic links resolve to the member pages while keeping the token in the URL for the page’s own JavaScript to read- a
301from your homepage page’s own slug URL to/, when you promoted a page to homepage, so you do not serve two copies of the same content
Custom domains
Type a hostname into Custom Domain on the deploy card and press Save. Two things happen:
- The domain is registered on the Cloudflare Pages project. A domain that is already registered is treated as success, not as an error.
- If your API token carries zone permissions, WordPuppi finds the zone, then updates or creates a proxied
CNAMErecord for that hostname pointing at<project>.pages.dev. A record that already points there is left alone.
If the DNS step fails, the domain is still added to the project and the toast tells you to check your DNS zone yourself.
The card then polls Cloudflare for verification status and shows it: “Verifying on Cloudflare Pages” while it is pending, and “Active on Cloudflare Pages” once it goes live.
Also set Site URL in generation settings to the domain you are serving from. That is what canonical links, the sitemap, and robots.txt are built against, and it is not derived from the domain field automatically.
Deployment history
GET /api/v1/cloudflare/deployments lists deployments for the project, and GET /api/v1/cloudflare/deployments/{id} returns one, each with its environment, URL, status, and creation time. The Platforms page and the deploy card both surface the latest one as a link.