Configure a custom v0 client
mainv0 export handles standard authentication via V0_API_KEY or Vercel OIDC, you should use createV0Client if you require custom authentication methods or specific client options.repository·main·Indexed 19 days ago
https://github.com/vercel/v0-sdkA TypeScript library for interacting with the v0 API, featuring tools for synchronous and streaming chat creation, preview retrieval, and Vercel OIDC authentication. The SDK includes @v0-sdk/ai-tools for AI SDK integration, @v0-sdk/react for SWR and AI SDK-based hooks, and a create-v0-sdk-app CLI for bootstrapping applications using the v0-clone template.
v0 export handles standard authentication via V0_API_KEY or Vercel OIDC, you should use createV0Client if you require custom authentication methods or specific client options.The application resolves credentials in a specific order: V0_API_KEY $\rightarrow$ browser-stored HTTP-only cookie $\rightarrow$ Vercel OIDC.
When using the browser-based API key dialog, the key is validated and stored in an HTTP-only cookie in the web app. It is then sent to the preview proxy, which stores it in its own isolated, partitioned HTTP-only cookie. This partitioning allows the proxy to receive the cookie inside the iframe without sharing the web app's cookies or exposing the key to the generated preview code.
| Environment | Web app $\rightarrow$ preview proxy | Preview proxy $\rightarrow$ web app |
|---|---|---|
| Local | http://localhost:3001 | http://localhost:3000 |
| Vercel Preview | Related Project's matching preview URL | Related Project's matching preview URL |
| Production | V0_PREVIEW_PROXY_URL, then Related Project | V0_CLONE_ORIGIN, then Related Project |
The SWR-based hooks automatically revalidate related mounted queries after successful mutations to ensure the UI stays in sync with the server.
Automatic Revalidation Rules:
useDeleteChat $\rightarrow$ revalidates chat lists.useRestoreMessage and useUpdateChatFiles $\rightarrow$ revalidate messages and files.useUpdateChat $\rightarrow$ revalidates the chat and chat lists.To prevent automatic revalidation, pass revalidate: false in the mutation configuration.
Tool keys in @v0-sdk/ai-tools are canonical operation names derived from their full operationId in the OpenAPI spec. They do not use friendly aliases. The naming convention follows a pattern where segments are concatenated: [segment].[operation] becomes [segment][Operation] (e.g., chats.create becomes chatsCreate).
Examples of canonical names:
chats.create $\rightarrow$ chatsCreatemessages.send $\rightarrow$ messagesSendorganizations.teams.listApiKeys $\rightarrow$ organizationsTeamsListApiKeysThe SDK provides two ways to handle streams:
You can return a stream directly from a server response using result.toResponse(), or consume it manually using an async iterator:
for await (const update of result.stream) {
// process update
}When consuming the v0 wire format directly on the client, use readV0Stream(response). Streaming is recommended for chat interfaces to allow the UI to update while v0 is thinking, editing files, or reporting usage.
for await (const update of result.stream) {
// process update
}If you are contributing to the create-v0-sdk-app package itself, use the following commands within the monorepo to install dependencies, build, typecheck, or run the development CLI with help documentation.
bun install
bun --filter create-v0-sdk-app build
bun --filter create-v0-sdk-app typecheck
bun --filter create-v0-sdk-app dev --helpFor production, you must deploy the host app and the preview proxy as two separate projects. For security, they should reside on different registrable domains (e.g., app.example.com and example-preview.net) to prevent generated code in the iframe from accessing the host app's origin.
apps/web as the host application.apps/preview-proxy on a different domain.vercel.json in both apps to include the other's project ID:{
"relatedProjects": ["prj_other_project_id"]
}V0_PREVIEW_PROXY_URL to the proxy's public origin.V0_CLONE_ORIGIN to the web app's public origin.V0_API_KEY on both projects, or leave them unset to use Vercel OIDC fallback.{
"relatedProjects": ["prj_other_project_id"]
}The v0 Clone is a monorepo containing two Next.js applications: apps/web (the host UI) and apps/preview-proxy (the preview origin). To run them locally:
cp examples/v0-clone/.env.example examples/v0-clone/.env.local.env.local with the following keys (though V0_API_KEY is optional for local dev):V0_API_KEYV0_PREVIEW_PROXY_URLV0_CLONE_ORIGINbun install
bun --filter v0-clone devLocal URLs are pre-configured:
http://localhost:3000http://localhost:3001If you are using a project generated via create-v0-sdk, run bun install and bun dev directly from the project directory.
cp examples/v0-clone/.env.example examples/v0-clone/.env.local
# Required env vars in .env.local
V0_API_KEY=
V0_PREVIEW_PROXY_URL=
V0_CLONE_ORIGIN=
# Run from root
bun install
bun --filter v0-clone devBecause V0_API_KEY must remain on the server, you must create backend routes (e.g., in Next.js) that use the server-side v0 SDK to proxy requests. This route handles the streaming message request from the client.
// app/api/v0/chats/[chatId]/messages/stream/route.ts
import { v0 } from 'v0'
export async function POST(request: Request, { params }: { params: Promise<{ chatId: string }> }) {
// Perform your own authentication and validation
const { chatId } = await params
const body = await request.json()
const result = await v0.messages.sendStream({ chatId, ...body })
return result.toResponse()
}To use the React hooks for building v0-powered applications, install the necessary packages based on your transport method.
For the AI SDK transport: Requires the AI SDK and its React integration.
For the SWR-based generated API hooks:
Requires swr to handle data fetching and caching.
# For AI SDK transport
npm install @v0-sdk/react react ai @ai-sdk/react
# For SWR-based hooks
npm install @v0-sdk/react react swrFor security, keep the v0 client on the server. React components should call authenticated proxy routes in your application rather than calling the v0 API directly.
useChat with V0TransportFor chat interfaces, the recommended pattern is using the AI SDK's useChat hook combined with V0Transport from @v0-sdk/react.
import { useChat } from '@ai-sdk/react'
import {
shouldResumeV0Chat,
toV0UIMessages,
V0Transport,
type MessagesListResponse,
type V0UIMessage,
} from '@v0-sdk/react'
import { useMemo } from 'react'
export function Chat({
chatId,
history,
}: {
chatId?: string
history: MessagesListResponse['messages']
}) {
const transport = useMemo(
() =>
new V0Transport({
chatId,
messages: history,
urls: {
create: '/api/v0/chats/stream',
send: (id) => `/api/v0/chats/${id}/messages/stream',
resume: (id) => `/api/v0/chats/${id}/resume',
},
}),
[chatId, history],
)
const chat = useChat<V0UIMessage>({
id: chatId,
messages: toV0UIMessages(history),
resume: shouldResumeV0Chat(history),
transport,
})
return <button onClick={() => chat.sendMessage({ text: 'Build a dashboard' })}>Send</button>
}toV0UIMessages(history): Converts v0 history to chronological AI SDK messages while preserving reasoning, files, and tool activity.shouldResumeV0Chat(history): Determines if a chat should be resumed.V0Transport.onChatCreated: A callback to handle the new chatId when a chat is first created.useStopMessage: Used to stop generation by calling the server, followed by chat.stop() from the AI SDK.import { useChat } from '@ai-sdk/react'
import {
shouldResumeV0Chat,
toV0UIMessages,
V0Transport,
type MessagesListResponse,
type V0UIMessage,
} from '@v0-sdk/react'
import { useMemo } from 'react'
export function Chat({
chatId,
history,
}: {
chatId?: string
history: MessagesListResponse['messages']
}) {
const transport = useMemo(
() =>
new V0Transport({
chatId,
messages: history,
urls: {
create: '/api/v0/chats/stream',
send: (id) => `/api/v0/chats/${id}/messages/stream',
resume: (id) => `/api/v0/chats/${id}/resume',
},
}),
[chatId, history],
)
const chat = useChat<V0UIMessage>({
id: chatId,
messages: toV0UIMessages(history),
resume: shouldResumeV0Chat(history),
transport,
})
return <button onClick={() => chat.sendMessage({ text: 'Build a dashboard' })}>Send</button>
}This example demonstrates a minimal Next.js application that integrates the v0 React SDK with the AI SDK's useChat hook. To run the demo locally, follow these steps:
V0_API_KEY to .env.local.bun from the repository root.cp .env.example .env.local
# Add V0_API_KEY, then from the repository root:
bun install
bun --filter react-chat dev