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.
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-rebilder-gateway -- --type=hello-world --ts
cd my-rebilder-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 — humans,
Googlebot, URLs I have not described — is forwarded to the origin unchanged.
STEPS
1. Scaffold a TypeScript Worker and add the dependency:
npm create cloudflare@latest my-rebilder-gateway -- --type=hello-world --ts
cd my-rebilder-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. Ask me for the real
values — see 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. Ask me for the hostname.
RULES — these are not style preferences
- Never invent a substantive value. Prices, opening hours, turnaround times,
what a service includes, whether booking is required — all of it comes from
me. If you do not have a value, ask. 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.
Write a helper that takes major units and multiply by 100 in one place.
Zero-decimal currencies (JPY, KRW, ISK) take whole units — do not multiply.
- Never fetch anything on the markdown path. The whole point is that a described
page is answered from the Worker bundle with no origin round-trip. If you
find yourself adding a fetch inside a resolver, stop and ask me.
- 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. This is additive, and `wrangler delete` must be a
complete rollback.
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 the store, e.g. store.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.