cms-cf-worker¶
A Cloudflare Worker that renders the public website at the edge from the CMS public v2 API. There are no per-page HTML files on a server: every response is built on demand by a single, generic, data-driven engine and cached close to the visitor.
Source:
src/index.ts,wrangler.toml,package.json.
One codebase, two workers¶
The repository ships two Workers from the same source tree, selected by the Wrangler environment that is deployed:
| Worker | Entry point | Role |
|---|---|---|
| Site worker | src/index.ts |
Renders pages, serves stylesheets and static text files, handles cache purge. Backed by a KV namespace. |
| Media worker | src/media/index.ts |
Streams media objects from S3 at the /cmp-media/* routes. Stateless; uses the edge Cache API only, no KV. |
This documentation is about the site worker (src/index.ts). The media
worker is mentioned only where it shares routes or deploy mechanics (see
Deploy and purge).
What the worker does¶
The worker is the public front door for a CMS-managed site (for example
wantskicks.com). For each request it:
- fetches the site's settings and page descriptors from the CMS public v2 API (cached aggressively at several layers);
- matches the request path to a page descriptor and renders HTML, either through a named builder or the generic declarative path;
- caches the rendered page and serves subsequent hits straight from the edge.
There is no hardcoded per-page code on the request path. Adding a new simple page type is configuration in the CMS, not a worker deploy. See Architecture.
Request lifecycle at a glance¶
handleRequest in src/index.ts walks a fixed sequence of steps. The numbered
comments in the source map one-to-one onto the stages below.
flowchart TD
A[Request] --> B{Admin endpoint?<br>/__cms/purge, /__cms/health}
B -- yes --> Z[Handle and stamp, bypass caches]
B -- no --> C{CSS asset path?<br>/_assets/styles/...}
C -- yes --> D[serveTemplateCss, fall back to bundled CSS]
C -- no --> E{Preview?<br>valid ?_preview= secret}
E -- no --> F{Edge cache hit?<br>Cache API}
F -- hit --> G[Return cached, X-CMS-Cache: hit]
F -- miss --> H[resolveSite: mem to Cache API to origin to KV]
E -- yes --> H
H --> I[Apply CSS override if env set]
I --> J{Static text?<br>ads.txt, robots.txt, favicon.ico}
J -- yes --> K[Serve from settings]
J -- no --> L[matchDescriptor, else notFoundDescriptor]
L --> M{Preview?}
M -- yes --> N[Render fresh, never read or write cache]
M -- no --> O[getOrRender: Cache API, render, KV fallback]
The exact steps, keyed to the src/index.ts comments:
- Step 1 -- admin endpoints.
/__cms/purgeand/__cms/healthtake absolute priority and skip every cache layer. See Deploy and purge. - Step 1b -- per-template stylesheet. A request for
/_assets/styles/<slug>/<version>.cssis served byserveTemplateCss(src/assets/serve.ts); on any miss it falls back to the bundled stylesheet. See CSS override. - Step 1c -- bundled stylesheet. The legacy single-file path
/_assets/styles/site.cssis served directly from the worker bundle. - Step 2 -- preview markers.
?_preview=<ADMIN_PURGE_SECRET>plus an optional?_ver=enables a fresh, cache-bypassing render for editors. - Step 3 -- cache-first short-circuit. For non-preview requests the worker checks the Cache API first and returns the cached body immediately on a hit. See Caching.
- Step 4 -- resolve site.
resolveSite(src/site/resolve.ts) loads the full site settings through its own three-tier cache (isolate memory, Cache API, origin) with KV as a fallback. - CSS override. When
CSS_OVERRIDE_SLUGandCSS_OVERRIDE_VERSIONare set on the worker, the resolved settings'active_templateis cosmetically overridden in memory. See CSS override. - Step 5 -- static text files.
/ads.txt,/robots.txt, and/favicon.icoare served from the cached settings. - Step 6 -- route and dispatch.
matchDescriptor(src/engine/router.ts) picks the best descriptor for the path; an unmatched path falls back tonotFoundDescriptor(src/engine/settings.ts). See Routing. - Step 7 -- render and cache. For public requests
getOrRender(src/cache/index.ts) returns the cached page, or renders fresh and write-throughs to both the Cache API and KV. Preview requests render fresh and never touch the cache.
Every response carries observability headers X-CMS-Cache (which layer served
it) and X-CMS-Render-Ms (wall-clock time in the worker). See
Caching for the full set of header values.
Source tree map¶
| Path | Responsibility |
|---|---|
src/index.ts |
Site worker entry point and request lifecycle. |
src/engine/router.ts |
matchDescriptor / matchPattern -- path to descriptor. |
src/engine/render.ts |
renderPage -- dispatch a matched descriptor to a builder. |
src/engine/generic.ts |
renderGeneric -- the code-free declarative builder. |
src/engine/settings.ts |
DEFAULT_PAGE_TYPES, getPageTypes, notFoundDescriptor. |
src/engine/sources.ts |
Executes a descriptor's declared upstream API calls. |
src/site/resolve.ts |
resolveSite -- the site-settings cache tiers. |
src/cache/index.ts |
getOrRender, purge, purgeSite -- page cache and purge. |
src/cms/client.ts |
cmsFetch -- authenticated GET against the CMS public v2 API. |
src/assets/serve.ts |
serveTemplateCss / parseTemplateCssPath -- template CSS. |
src/layout/index.ts |
renderLayout, buildStyle, the Handlebars-like renderTemplate. |
src/admin/purge.ts |
POST /__cms/purge handler. |
src/pages/*.ts |
The named builders (homepage, article, category, author, ...). |
src/media/index.ts |
The separate media worker. |
wrangler.toml |
Worker names, routes, env vars, KV bindings for every env. |
Where to go next¶
- Architecture -- the generic engine and the template renderer.
- Routing -- how a path picks a descriptor.
- Caching -- the four cache layers and their exact TTLs.
- CSS override -- the per-worker stylesheet override.
- Deploy and purge -- environments, deploy scripts, secrets, purge.
- Managing pages and designs -- the no-code operator guide for editors.