Cloudflare Worker & edge
A fetch-handler factory for web-standard edge runtimes (@rebilder/gateway/edge): a complete worker in five lines, with origin pass-through included.
Last updated
On this page
From nothing to deployed#
Four commands and one file of your own content. This puts the gateway in front of a site you already have, on a domain already on Cloudflare, on any plan including Free.
npm create cloudflare@latest my-mumm-gateway -- --type=hello-world --ts
cd my-mumm-gateway
npm install @rebilder/gatewayThen replace src/index.ts with the worker below, add your pages, and point wrangler.jsonc at your zone:
"routes": [
{ "pattern": "example.com/*", "zone_name": "example.com" },
{ "pattern": "www.example.com/*", "zone_name": "example.com" }
]npx wrangler login
npx wrangler deployVerify with curl -sI https://example.com/your-page -H "Accept: text/markdown": seeing content-type: text/markdown and x-rebilder-path: markdown means you are live. npx wrangler tail streams the events.
Hand this to your coding agent#
If you would rather not wire it by hand, paste this into Claude Code, Cursor, or whatever you build with. It is written to be unambiguous about the parts that are easy to get wrong.
Set up a Cloudflare Worker that puts @rebilder/gateway in front of my site.
WHAT IT DOES
The Worker sits on a route in front of the origin. When an AI agent requests a
URL with `Accept: text/markdown` AND that URL is one I have described, it
answers with clean markdown rendered from typed data. Everything else is
forwarded to the origin unchanged: humans, Googlebot, URLs I have not described.
STEPS
1. Scaffold a TypeScript Worker and add the dependency:
npm create cloudflare@latest my-mumm-gateway -- --type=hello-world --ts
cd my-mumm-gateway && npm install @rebilder/gateway
2. Read node_modules/@rebilder/gateway/README.md before writing anything. Do
not work from memory of this prompt.
3. Create `src/content.ts`: a `Map<string, DocumentSource>` keyed by pathname,
and a `Map<string, CollectionSource>` for index pages. Read real values
from authoritative business sources, following the rules below.
4. Create `src/gateway-config.ts` exporting a `GatewayConfig` whose `document`
and `collection` resolvers are `Map.get` on the normalised pathname, plus a
pure synchronous `match` router returning 'document', 'collection', or null.
5. Make `src/index.ts`:
import { createGatewayFetchHandler } from '@rebilder/gateway/edge'
export default { fetch: createGatewayFetchHandler(gatewayConfig) }
6. In wrangler.jsonc, set `routes` to my zone. Use the configured hostname.
Ask only if the deployment target is missing or ambiguous.
IMPLEMENTATION REQUIREMENTS
- Never invent a substantive value. Read prices, opening hours, turnaround
times, what a service includes and whether booking is required from
authoritative business sources. Ask only for unavailable facts the task
needs. Do not write a plausible-looking placeholder into content.ts; it will
ship, and an agent will quote it.
- Money is in MINOR UNITS. { amount: 180, currency: 'GBP' } is £1.80, not £180.
Use the currency’s minor-unit exponent when converting major units. Keep
decimal arithmetic exact and reject unsupported precision.
- Serve the described pages from bundled or cached sources. If remote
resolution is needed, bound its timeout, verify freshness and keep the origin
fallback.
- A resolver returns null when the URL is not that kind of page. null means
"forward to the origin", which is always a safe answer.
- Forward the origin's response as-is. Do not rewrite its status, do not turn a
502 into a friendly page, do not follow its redirects inside the Worker.
- Do not change the origin. Keep a rollback path that removes the Worker route
and restores direct origin serving.
WHEN YOU ARE DONE
Tell me which pathnames now serve markdown and which pages I still need to
describe. Then verify against the deployed site, one real URL of each kind:
curl -sI https://MY-DOMAIN/PATH -H 'Accept: text/markdown' # expect text/markdown
curl -sI https://MY-DOMAIN/PATH # expect my normal HTML
npx rebilder check https://MY-DOMAIN/PATH # grades the page
If you cannot answer "which URLs now serve markdown", the setup is not done.A complete worker#
The adapter needs no Cloudflare imports: (req: Request) => Promise<Response> is the whole contract, and export default { fetch } satisfies a CF Worker’s fetch handler without any workers-types coupling. Deploy it on a route in front of the store:
// worker.ts: deploy on a route in front of your site, e.g. example.com/*
import { createGatewayFetchHandler } from '@rebilder/gateway/edge'
import { gatewayConfig } from './gateway-config'
export default { fetch: createGatewayFetchHandler(gatewayConfig) }That is a complete worker: agent traffic with a matching source gets the standard markdown response; everything else is fetch(req)-ed to the origin unchanged, which is the standard CF Worker reverse-proxy pattern, so browsers and crawlers get the canonical HTML exactly as if the worker weren’t there.
Serving the non-markdown path yourself#
Pass options.fallback: (req) => Response | Promise<Response> to serve the non-markdown path yourself instead of proxying, which is useful for workers that are not fronting an origin, or for tests.
Latency note#
A gateway-internal error is contained like every other failure: the request falls through to fallback/origin, never a 500.
Vercel Edge & other WinterCG runtimes#
The same plain fetch handler works on Vercel Edge Functions (or any WinterCG runtime): export it as the handler. Use options.fallback there, since Vercel Edge functions don’t sit in front of an origin the way a route-mounted CF Worker does. In Next.js projects, prefer the ./next adapter, which plugs into middleware natively.