Documentation Index
Fetch the complete documentation index at: https://docs.vertz.dev/llms.txt
Use this file to discover all available pages before exploring further.
@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:| Route | Handler |
|---|---|
/api/* | Server handler (entities, auth, services) |
/_vertz/image | Image optimizer (if configured) |
| Everything else | SSR |
[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:| Header | Value |
|---|---|
Content-Security-Policy | default-src 'self'; script-src 'self' 'nonce-<random>'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; |
Strict-Transport-Security | max-age=31536000; includeSubDomains |
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
X-XSS-Protection | 1; mode=block |
Referrer-Policy | strict-origin-when-cross-origin |
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 site | Full-stack (Workers) | |
|---|---|---|
| Server | None — static files only | Cloudflare Worker with SSR |
| Data | Build-time only | Per-request (queries, auth) |
| Package | Custom build script | @vertz/cloudflare |
| Caching | Edge CDN (immutable assets) | ISR via KV (optional) |
| Use case | Landing pages, marketing | Apps with dynamic data |
Static Sites
Deploy static sites and landing pages
SSR
How Vertz SSR works under the hood