website/src/content/docs/connect/vercel.mdx
Make sure your project is configured correctly for Vercel deployment.
<Tabs> <Tab title="Next.js">Your Next.js project should have the following structure:
src/app/api/rivet/[...all]/route.ts: RivetKit route handlersrc/actors.ts: Actor definitions and registrySee the Next.js quickstart or the Next.js example to get started.
</Tab> <Tab title="Hono">Your Hono project needs:
vercel.json file with the Hono framework specified:{
"framework": "hono"
}
"hono" for Vercel to recognize the framework:// You MUST import from "hono" for Vercel to detect this as a Hono app
import { Hono } from "hono";
import { registry } from "./actors.ts";
const app = new Hono();
app.all("/api/rivet/*", (c) => registry.handler(c.req.raw));
export default app;
.ts file extensions in imports and configure your tsconfig.json:{
"compilerOptions": {
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": true
}
}
See the Hello World example for a complete example.
For more details on Hono deployments, see Vercel's Hono documentation.
</Tab> <Tab title="Other">Vercel currently supports Next.js and Hono frameworks for RivetKit deployments.
For other frameworks, consider deploying to Railway, Kubernetes, or another platform.
</Tab> </Tabs> </Step> <Step title="Deploy to Vercel">Add a GitHub action to automatically create isolated Rivet namespaces for each PR:
Add these secrets to your GitHub repository:
RIVET_CLOUD_TOKEN: Get from Rivet Dashboard → Settings → Advanced → Cloud API TokensVERCEL_TOKEN: Get from Vercel Account SettingsCreate .github/workflows/rivet-preview.yml:
name: Rivet Preview
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [main]
concurrency:
group: rivet-preview-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
rivet-preview:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: rivet-dev/preview-namespace-action@v1
with:
platform: vercel
rivet-token: ${{ secrets.RIVET_CLOUD_TOKEN }}
vercel-token: ${{ secrets.VERCEL_TOKEN }}
Error: ENOENT: no such file or directory, mkdir '.../rivetkit/.../state'
Cause: The RIVET_ENDPOINT environment variable is not configured. RivetKit falls back to the file system driver, which fails in Vercel's read-only serverless environment.
Solution: Ensure RIVET_ENDPOINT is set with your Rivet endpoint using the URL auth format:
RIVET_ENDPOINT=https://my-namespace:sk_****@api.rivet.dev
If using the preview-namespace-action, this is configured automatically.
</Accordion> <Accordion title="Metadata endpoint missing clientEndpoint">The /api/rivet/metadata endpoint returns data but clientEndpoint, clientNamespace, and clientToken are missing.
Cause: The RIVET_PUBLIC_ENDPOINT environment variable is not configured. This tells the metadata endpoint what connection info to provide to clients.
Solution: Set RIVET_PUBLIC_ENDPOINT with the publishable token (for client access):
RIVET_PUBLIC_ENDPOINT=https://my-namespace:pk_****@api.rivet.dev
If using the preview-namespace-action, this is configured automatically.
</Accordion> <Accordion title="401 Authentication Required from Rivet Actor">Rivet fails to connect to your Vercel deployment with a 401 error mentioning "Authentication Required".
Cause: Vercel Deployment Protection is blocking requests from Rivet.
Solution:
x-vercel-protection-bypass with your bypass secretIf using the preview-namespace-action, this is configured automatically.
</Accordion> </AccordionGroup>