Skip to content
SDK docs menu

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.

Scaffold and install
npm create cloudflare@latest my-mumm-gateway -- --type=hello-world --ts
cd my-mumm-gateway
npm install @rebilder/gateway

Then replace src/index.ts with the worker below, add your pages, and point wrangler.jsonc at your zone:

wrangler.jsonc: the only required edit
"routes": [
  { "pattern": "example.com/*", "zone_name": "example.com" },
  { "pattern": "www.example.com/*", "zone_name": "example.com" }
]
Ship it
npx wrangler login
npx wrangler deploy

Verify 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.

Prompt
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
// 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.