@vertz/cloudflare provides createHandler — a single function that wires up your API, SSR, security headers, and optional ISR caching into a Cloudflare Worker module.
Quick start
- Routes
/api/*requests to your server (entities, auth, services) - Renders all other routes via SSR
- Adds security headers with per-request nonce-based CSP
- Detects
requestHandleronServerInstancefor auth-aware routing
Configuration
CloudflareHandlerConfig
SSR module config
The zero-boilerplate form passes your app module directly:Route splitting
The handler splits requests by URL path:
Static assets (JS, CSS, images) are served by Cloudflare’s
[assets] directive in wrangler.toml before the Worker runs — they never reach createHandler.
Custom apiPrefix
If your server uses a non-defaultapiPrefix, match it in the handler:
apiPrefix is omitted from createHandler, it reads app.apiPrefix at
runtime — so if you set it on createServer, the handler picks it up automatically.
Auth-aware routing
When your server uses auth (OAuth, sessions),createServer returns a ServerInstance with a requestHandler method that routes both auth and entity requests. The handler detects this automatically:
/api/auth/signin, /api/auth/callback, etc. are all handled.
If your app is a plain AppBuilder without auth, the handler falls back to app.handler automatically.
Security headers
Security headers are enabled by default. Every response includes:
Each request gets a unique cryptographic nonce for CSP. Script tags in SSR output use this nonce.
To disable security headers (not recommended):
ISR caching
ISR (Incremental Static Regeneration) caches SSR responses in Cloudflare KV. This gives you near-static performance with dynamic content.How it works
- First request — SSR renders the page, stores the HTML in KV, returns the response (
X-Vertz-Cache: MISS) - Subsequent requests (within TTL) — serves from KV instantly (
X-Vertz-Cache: HIT) - After TTL expires — serves the stale page immediately, re-renders in the background via
ctx.waitUntil()(X-Vertz-Cache: STALE)
Setup
Add a KV namespace inwrangler.toml:
Cache behavior
- Only SSR routes are cached — API requests (
/api/*) are never cached - Nonces are stripped before caching and re-injected on each request (each response gets a fresh CSP nonce)
- KV entries expire at 2x the TTL to allow stale-while-revalidate to work
- KV lookup failures are non-fatal — the handler falls through to SSR
beforeRender middleware
UsebeforeRender to run logic before SSR on non-API routes. Return a Response to short-circuit, or undefined to proceed with SSR:
beforeRender receives the Request and the Worker env bindings. It runs after API routing but before SSR and ISR cache checks.
Wrangler configuration
The
[assets] directive serves static files (JS bundles, CSS, images) directly from Cloudflare’s
edge — they never hit the Worker. Only dynamic requests (API calls, page navigations) reach
createHandler.Deploy
How it differs from static deployment
Static Sites
Deploy static sites and landing pages
SSR
How Vertz SSR works under the hood