The docs site fanned out into one CF Pages project per DOCS_SECTION, stitched by
an edge worker whose *.pages.dev origins had gone stale — so every
/docs/projects/* and /docs/services/{iam,kms,platform}/* page returned 530, and
those products were never actually merged into docs.hanzo.ai. Collapse it: one
unified static export → one hanzo-docs Pages project → the router passes every
path straight through.
- source.config.ts: build the whole doc set in one pass (core + every service
incl. iam/kms/platform + every synced OSS project). The next.config
ProjectDocsFallback + remarkPassthroughUnknownJsx neutralise foreign MDX from
ported docs, so a single build is safe.
- workers/docs-router: pass-through to the single hanzo-docs origin — nothing to
stitch, no stale section origin to 530.
- OpenAPI: /docs/openapi/<svc> reference pages are generated at build time from
the specs (gen-openapi-pages.ts wired into pre-build.ts; specs synced by
sync-openapi.sh). The runtime <APIPage> is export-disabled (deep operation
slugs break prerender); static per-service pages export cleanly and can't 530.
The openapi index links to the generated reference pages.
- public/_redirects: alias the console product "Docs" deep-links that live under
/docs/services or /docs/projects so console → docs always resolves.
- deploy-docs.yml: one full export (NEXT_EXPORT=1), ships content + router
together. Remove the four dead per-section deploy workflows.
Verified: full export builds green in one pass under Turbopack (1628 pages) and a
crawl of every internal link from / and /docs resolves 200 — 1320/1320, zero 404,
zero 530. iam/kms/platform/projects all 200 and reachable in nav.
Each federated docs section (IAM, KMS, Platform) builds unique layout
and page chunks that only exist on its CF Pages origin. The Worker was
routing all /_next/ requests to the main origin, causing 404s for
section-specific chunks (e.g. app/docs/layout-*.js), which crashed
client-side hydration and broke sidebar navigation.
Now the Worker checks the Referer header on /_next/ requests to
determine which section the browser is rendering, and routes to that
section's origin first, falling back to main if the asset is missing.