Bun, Deno, Netlify and Vercel
Run the gateway on Bun, Deno, Netlify Edge Functions or Vercel: wrap the fetch handler you already have, or add routing middleware in front of your site.
Last updated
Wrap the handler you already have
Each of these runtimes serves requests through a web-standard (request) => Response function. Wrap yours with the fetch middleware: agents asking for markdown are answered by the gateway, and every other request reaches your handler with Vary: Accept added to its response.
Using a framework on one of these runtimes? Use that framework’s recipe on the frameworks page. Cloudflare Workers have their own adapter.
Bun
// server.ts
import { createFetchMiddleware } from '@rebilder/gateway/fetch'
import { gatewayConfig } from './gateway-config'
import { app } from './app' // your existing (request) => Response handler
const gateway = createFetchMiddleware(gatewayConfig)
Bun.serve({ fetch: (request) => gateway(request, () => app(request)) })Requests matched by the routes option of Bun.serve skip fetch. If you use routes, wrap those handlers the same way.
Deno
// main.ts
import { createFetchMiddleware } from '@rebilder/gateway/fetch'
import { gatewayConfig } from './gateway-config.ts'
import { app } from './app.ts' // your existing (request) => Response handler
const gateway = createFetchMiddleware(gatewayConfig)
Deno.serve((request) => gateway(request, () => app(request)))Netlify Edge Functions
// netlify/edge-functions/rebilder.ts
import type { Config, Context } from '@netlify/edge-functions'
import { createFetchMiddleware } from '@rebilder/gateway/fetch'
import { gatewayConfig } from '../../gateway-config.ts'
const gateway = createFetchMiddleware(gatewayConfig)
export default (request: Request, context: Context) => gateway(request, () => context.next())
export const config: Config = { path: '/*', excludedPath: ['/*.css', '/*.js'] }The edge function sits in front of your site, whatever built it. Agents are answered at the edge; everything else continues to your site through context.next(). Narrow path to the pages your sources answer, and keep static assets in excludedPath.
Vercel
In a Next.js project, use the Next.js adapter. For any other project, add Routing Middleware at the project root:
// middleware.ts at the project root (Vercel Routing Middleware, outside Next.js)
import { next } from '@vercel/functions'
import { handleRequest, negotiationHeaders } from '@rebilder/gateway/fetch'
import { gatewayConfig } from './gateway-config'
export default async function middleware(request: Request) {
const served = await handleRequest(request, gatewayConfig)
return served ?? next({ headers: Object.fromEntries(negotiationHeaders(gatewayConfig, new URL(request.url))) })
}Routing Middleware runs before your site and cannot read its response, so the recipe answers agents with handleRequest and passes the negotiation headers to next() for everything else. Limit it to your pages with export const config = { matcher: [...] }.
If a single Vercel Function already serves your whole site, give the edge adapter your handler as the fallback instead:
// api/[...path].ts: a Vercel Function that answers the whole site itself
import { createGatewayFetchHandler } from '@rebilder/gateway/edge'
import { gatewayConfig } from '../gateway-config'
import { app } from '../app' // your existing (request) => Response handler
export default { fetch: createGatewayFetchHandler(gatewayConfig, { fallback: app }) }