Cloudflare
Cloudflare Workers can serve a directory of static assets directly: no separate compute,
no SPA shim. This is how htmlpress.dev ships, and the same
wrangler.jsonc shape works for any htmlpress site. Workers static assets
also read the _headers file every build writes.
Build the site
htmlpress build
Output lands in .htmlpress/build/.
Configure wrangler.jsonc
Drop this at your project root:
{
"name": "my-docs",
"compatibility_date": "2026-04-01",
"workers_dev": true,
"assets": {
"directory": ".htmlpress/build",
"not_found_handling": "404-page",
},
}
Three fields do the heavy lifting:
| Field | Purpose |
|---|---|
assets.directory |
Points Wrangler at the htmlpress build output. Every file is served as-is. |
assets.not_found_handling |
Answers unknown paths with the build's 404.html. |
workers_dev |
Gives you a <name>.<account>.workers.dev preview URL
while testing.
|
Deploy from your machine
htmlpress build
npx wrangler deploy
The first run prompts for wrangler login to authorize against your
Cloudflare account.
Deploy with GitHub Actions
name: deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: 24
- run: npx gethtmlpress build
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
Create a scoped API token at My Profile → API Tokens (the "Edit Cloudflare Workers" template grants exactly what you need) and store both values as repo secrets.
Without a workflow, Workers Builds can run the build itself: connect the repository in
the dashboard and add a build block to wrangler.jsonc, as
htmlpress.dev does with "build": { "command": "pnpm build:docs" }.
Custom domain
Add a routes block once your zone is on Cloudflare:
{
"name": "my-docs",
"compatibility_date": "2026-04-01",
"assets": { "directory": ".htmlpress/build", "not_found_handling": "404-page" },
"routes": [{ "pattern": "docs.example.com", "custom_domain": true }],
}
custom_domain: true tells Cloudflare to provision a managed domain: DNS,
certificate, and route are all handled for you. Set site to the same domain
in htmlpress.yaml so absolute URLs in the sitemap line up.
The htmlpress repo's own wrangler.jsonc is a working reference; see the
project root.
Markdown for agents
AI agents ask for a page as Markdown by sending Accept: text/markdown.
Static assets always answer with HTML, so add a URL Rewrite Rule to your zone that
points those requests at the page's
Markdown copy: /guides/build/ has
/guides/build/index.md beside its HTML. URL Rewrite Rules are available on
every plan, including Free, and the site stays fully static.
In the dashboard, open your domain, go to Rules → Overview → Create rule → URL Rewrite Rule, and fill in:
| Field | Value |
|---|---|
| Rule name | Markdown for agents |
| If incoming requests match | Custom filter expression (below) |
| Path |
Rewrite to → Dynamic →
concat(http.request.uri.path, "index.md")
|
| Query | Preserve |
any(http.request.headers["accept"][*] contains "text/markdown") and ends_with(http.request.uri.path, "/")
Page URLs end in /, so the rule only touches pages. Static assets serve
.md files as text/markdown, so the response type needs no
extra rule.
Deploy a build that contains the Markdown copies before enabling the rule. Otherwise an agent asking for Markdown gets a 404.
See also
- AI Agents: what the build publishes for agents.
-
Site Metadata:
sitepowers absolute URLs and the sitemap. - Deployment: back to the host index.
Created with ❤ and Htmlpress