Vercel
Deploy Rebask to Vercel with the Build Output API.
Install the Vercel adapter
pnpm add -D @rebask/vercelAdd vercelAdapter() to your Vite plugins:
// vite.config.ts
import { vercelAdapter } from "@rebask/vercel"
plugins: [rsc(), react(), rebask(), vercelAdapter()]The adapter only runs during a Vercel build, when VERCEL is set.
Configure the adapter:
vercelAdapter({
runtime: "nodejs24.x",
memory: 1024,
maxDuration: 60,
regions: ["iad1"],
})| Option | Type | Default | Description |
|---|---|---|---|
runtime | nodejs${number}.x | nodejs24.x | Node.js runtime for both generated functions. |
memory | number | Platform default | Memory in MB. |
maxDuration | number | Platform default | Maximum execution time in seconds. |
regions | string[] | Platform default | Function regions. |
images | ImagesConfig | Auto-detected, otherwise unset | Vercel image optimization. See Images. |
disablePrerender | boolean | false | Skip prerender packaging and PPR. Requires a custom cacheHandler. |
Function settings apply to both the server and proxy functions.
Build for Vercel:
VERCEL=1 vite buildVercel sets VERCEL automatically. Use VERCEL=1 for a local adapter build.
Writes .vercel/output (Build Output API). Deploy with the Vercel dashboard, Git integration, or:
vercel deploy --prebuiltLocal testing
Test with the Vercel CLI:
vercel devvercel dev may rebuild the app. For a prebuilt deployment, run vercel build and then vercel deploy --prebuilt.
What the adapter packages
On a Vercel build the adapter turns the Rebask production output into:
- A serverless function for HTML, RSC, resume, actions, and route handlers
- A proxy function when
proxy.tsmatches routes - Static assets under
.vercel/output/static - Prerender entries for PPR routes: shared shells, layout intermediate shells (from layout
prerenderParams), and static paths - Routing so the CDN can serve a shell and chain a resume request into the function
Shared dynamic routes use allowQuery for every dynamic segment (including the leaf). That way a full page upgrade for one param value cannot be reused for another (cache poison).
Known intermediate shells are separate, more specific prerender routes produced only at build time. Runtime never invents new intermediate keys.
Request flow (PPR HTML)
- User GET — CDN matches a prerender route and serves the static shell (
x-vercel-cache: PRERENDERorHITafter warm). - Resume POST — platform chains into the function with
x-rebask-resumeto fill Suspense holes for this request. - Background upgrade — after resume finishes, the adapter schedules a revalidate (
x-prerender-revalidate). Rebask renders a full page and Vercel writes it into that prerender slot for the currentallowQueryvalues.
Later GETs for the same variation can be a full document (x-vercel-cache: HIT) with no shell stream.
| Matched entry | First paint | Upgrade writes |
|---|---|---|
| Shared shell (unknown param combo) | Shared fallback | Full page for that param set |
| Intermediate (build list) | Intermediate fallback | Full page for remaining params |
| Already upgraded variation | Full page | Refresh full page when stale |
Stale shared or intermediate entries are refreshed by the platform (ISR / SWR). Upgrade always targets a full page, not a new intermediate shell.
Request flow (RSC payloads)
Each page and layout payload has a prerender entry for the full payload, and one for its shell. A static page that read no request data at build time has no separate shell, since its shell is the full payload. A shell never holds request data, so Vercel stores it as is. A tail always goes to the function.
Vercel stores whatever a prerender invocation returns, even a no-store response, so the full payload entry starts empty and chains every request into the function:
- User GET — the CDN serves the empty entry and chains the request into the function, which renders the payload for this visitor.
- Background fill — if that payload read no request data, the adapter has Vercel store it, and later GETs are a
HIT.
How this differs from Node / vite preview
| Node (default cache) | Vercel | |
|---|---|---|
| Where page HTML/RSC live | Rebask html: / rsc: keys (memory or cacheHandler) | Vercel prerender CDN entries |
| Shared shell | One key per route file | One prerender pattern + allowQuery |
| Intermediate shells | Build list; can refill known keys at runtime if missing/stale | Build routes and fallbacks only |
| Unknown combo | Shared → promote toward full pathname in Rebask cache | Shared → full page in that allowQuery slot |
| Resume | App streams shell + dynamic in one response | CDN shell, then resume POST to the function |
"use cache" | Your cacheHandler or default | Your cacheHandler if set; otherwise Vercel Runtime Cache |
HTML and RSC page bodies are not written through a custom
cacheHandler on Vercel. Use cacheHandler for
"use cache" data only (for example Redis). Omit it to
use Vercel’s runtime cache for "use cache".
Page responses on Vercel do not include x-rebask-cache but x-vercel-cache. With disablePrerender, the custom cacheHandler owns page caching and x-rebask-cache remains available.
See also Partial Pre-Rendering and intermediate shells.
Images
Image optimization can use Vercel’s /_vercel/image API instead of running the image handler in
the serverless function:
- If
rebaskImage()is configured, the adapter uses that configuration automatically. - If both
rebaskImage()and the adapterimagesoption are set,rebaskImage()wins and the adapter warns. - If only
imagesis set, the adapter uses it. - If neither is set, requests use the default
rebask.image.tshandler, which may bundle Sharp.
The images option accepts Vercel’s image configuration, including sizes, formats, minimumCacheTTL, domains, remotePatterns, and localPatterns.
When image optimization is configured, /_rebask/image routes to /_vercel/image. See
Images for the Rebask image configuration.
disablePrerender
Set disablePrerender: true only when you supply a custom
cacheHandler and want to own page caching yourself. The adapter then skips prerender packaging and PPR wiring. The build fails if no
custom cacheHandler is configured.