ADR-0002: Serve the docs site via Cloudflare Workers Static Assets (not Pages)
ADR-0002: Serve the docs site via Cloudflare Workers Static Assets (not Pages)
Section titled “ADR-0002: Serve the docs site via Cloudflare Workers Static Assets (not Pages)”- Status: Accepted (2026-05-24)
- Deciders: @ArneFfm
- Master design impact: Amends D18 (still Starlight/Astro for content) and D20 (subdomain unchanged). No new D-row needed.
- Supersedes the Pages hosting choice in spec 11 §7.
Context
Section titled “Context”Spec 11 §7 originally picked Cloudflare Pages as the hosting platform for docs.nowyourlink.com. Two facts changed our minds during PR-A2:
- Cloudflare announced Workers Static Assets as the recommended hosting target for new static sites (late 2024). Pages is in maintenance mode — supported but no longer the canonical path. Cloudflare publishes an official Pages → Workers migration guide.
- PR #65’s
cloudflare_pages_project.docsTerraform never actually applied in production (deploy.yml isworkflow_dispatch, and the first apply run for this project hadn’t happened yet). The PR-A2 preview workflow failed against[code: 8000007] Project not found. Migrating now costs roughly the same as fixing the chicken-and-egg — and avoids leaving a deprecated hosting layer in place.
Decision
Section titled “Decision”docs.nowyourlink.com ships as a Cloudflare Worker with the [assets] binding, not a Pages project.
apps/docs-site/wrangler.jsoncdeclaresassets.directory = "./dist",assets.binding = "ASSETS", and two environments (preview,production) that map to two Workers (nowyourlink-docs-preview,nowyourlink-docs-production).- Starlight + Astro stay unchanged —
astro buildstill emits a staticdist/(D18 holds). - A thin Hono worker at
apps/docs-site/src/worker/{index,app}.tsis the entrypoint per ADR-0001. Defaultrun_worker_first = falsemeans the asset router serves matched paths and Hono only sees fall-throughs (currently just 404s; this is the seam through which spec 11 §8’s/internal/*Access-gated routes will land). - Custom-domain mapping moves from
cloudflare_pages_domain+ a CNAME flattening DNS record to a singlecloudflare_workers_custom_domainresource (infra/terraform/workers_docs.tf). CF provisions the DNS record and edge cert automatically — the explicit CNAME from the Pages pattern (master D24 rationale) is no longer needed. - The CI deploy flow is the same shape as every other Worker in the monorepo:
wrangler deploy --env preview|production. The previously special-casedwrangler pages deploystep is gone.
Alternatives considered
Section titled “Alternatives considered”| Option | Why rejected |
|---|---|
| Stay on Pages, fix the chicken-and-egg (apply TF first, then deploy) | Solves the immediate failure but leaves us on a maintenance-mode platform with a special-case deploy command and a duplicate DNS record. The Wave 2 migration would land within months anyway. |
Workers Static Assets WITHOUT a Hono worker (main unset, pure asset serving) | Contradicts the repo convention that every HTTP-serving Worker uses Hono (CLAUDE.md + ADR-0001). It also closes the seam we need for spec 11 §8’s /internal/* Access-gated routes. |
Workers Static Assets WITH run_worker_first = true | Routes every static byte through the Hono worker for no functional gain. Default-false keeps the hot path edge-cached. |
What stays unchanged
Section titled “What stays unchanged”- Starlight / Astro / Pagefind /
astro-mermaid— content authoring and the build pipeline are identical. docs/superpowers/source of truth — sync-specs.mjs still runs inprebuild.- Public hostname —
docs.nowyourlink.com, EN primary + DE secondary, per master D19/D20. - Spec 11 §8
/internal/*Access gate — the seam is now the Hono worker rather than Pages Access; the gate itself still lands as a Wave 2 PR (W2-4).
Consequences
Section titled “Consequences”- Single deploy surface.
wrangler deployis the only command, matching apps/web/api/admin/queue/cron/webhook. - No more Pages project lifecycle to track in Terraform.
cloudflare_pages_project+cloudflare_pages_domain+cloudflare_dns_record.docsare gone. The replacement is onecloudflare_workers_custom_domainresource. - Per-PR preview limitation (carried forward). The preview environment is a single shared Worker (
nowyourlink-docs-preview) overwritten per push. Parallel docs PRs would clobber each other’s preview. Upgrade path:wrangler versions upload --preview-alias pr-<N>for per-PR isolated alias URLs. Tracked as a carry-forward innext_session_goal_11_docs.txt. - #65’s Terraform is replaced, not extended.
infra/terraform/pages_docs.tfis renamed toworkers_docs.tfand its contents are rewritten. Nocloudflare_pages_projectever applied in production, so there is no resource to destroy —terraform applywill simply not find the old resource in state. - PR-A2 (the original “Cloudflare Pages preview + prod deploy workflow”) is repurposed into the Pages→Workers pivot. The PR description is rewritten to match.