The Vercel integration provides a pre-built codec and three pre-bound factories for the Vercel AI SDK. It maps Vercel's UIMessageChunk events to UIMessage objects, so you can use AI Transport with useChat without writing a custom codec.
1
2
3
4
5
6
import {
UIMessageCodec,
createClientTransport,
createServerTransport,
createChatTransport,
} from '@ably/ai-transport/vercel';React-side hooks (useChatTransport, useMessageSync, ChatTransportProvider) live on the React hooks reference.
UIMessageCodec
A pre-built Codec<UIMessageChunk, UIMessage> for the Vercel AI SDK. It handles encoding and decoding of Vercel's message types over Ably channels.
You do not need to import UIMessageCodec directly if you use the Vercel-pre-bound transport factories or the React hooks; they bind the codec automatically.
1
import { UIMessageCodec } from '@ably/ai-transport/vercel';Create a Vercel client transport
function createClientTransport(options: VercelClientTransportOptions): ClientTransport<UIMessageChunk, UIMessage>Pre-bound version of the core createClientTransport with codec: UIMessageCodec already supplied and api defaulted to /api/chat.
1
2
3
4
5
6
7
import * as Ably from 'ably';
import { createClientTransport } from '@ably/ai-transport/vercel';
const ably = new Ably.Realtime({ authUrl: '/auth' });
const channel = ably.channels.get('conversation-42');
const transport = createClientTransport({ channel });Parameters
optionsrequiredVercelClientTransportOptionsReturns
ClientTransport<UIMessageChunk, UIMessage>
A ClientTransport typed for Vercel's UIMessage content. See ClientTransport for the full surface.
Create a Vercel server transport
function createServerTransport(options: VercelServerTransportOptions): ServerTransport<UIMessageChunk, UIMessage>Pre-bound version of the core createServerTransport with codec: UIMessageCodec already supplied.
1
2
3
4
5
6
7
import Ably from 'ably';
import { createServerTransport } from '@ably/ai-transport/vercel';
const ably = new Ably.Realtime({ key: process.env.ABLY_API_KEY });
const channel = ably.channels.get('conversation-42');
const transport = createServerTransport({ channel });Parameters
optionsrequiredVercelServerTransportOptionsReturns
ServerTransport<UIMessageChunk, UIMessage>
A ServerTransport typed for Vercel's UIMessage content. See ServerTransport for the full surface.
Create a chat transport
function createChatTransport(transport: ClientTransport<UIMessageChunk, UIMessage>, chatOptions?: ChatTransportOptions): ChatTransportCreate a ChatTransport adapter around an existing ClientTransport. The ChatTransport is the object you pass to Vercel's useChat as transport. In most cases you will use the ChatTransportProvider and read the adapter via useChatTransport rather than calling this factory directly.
1
2
3
4
import { createClientTransport, createChatTransport } from '@ably/ai-transport/vercel';
const clientTransport = createClientTransport({ channel });
const chatTransport = createChatTransport(clientTransport);Parameters
transportrequiredClientTransport<UIMessageChunk, UIMessage>chatOptionsoptionalChatTransportOptionsReturns
ChatTransport
A ChatTransport adapter that satisfies Vercel's useChat({ transport }) parameter shape.
ChatTransport
The adapter object Vercel's useChat expects as transport. Has two methods, both invoked by useChat internally; you typically pass the adapter and never call these directly.
Send messages
sendMessages(options: SendMessagesOptions): Promise<ReadableStream<UIMessageChunk>>Send messages and return a streaming response of UIMessageChunk events. Called by useChat when the user submits a new message or requests a regeneration.
Reconnect to a stream
reconnectToStream(options: { chatId: string }): Promise<ReadableStream<UIMessageChunk> | null>Reconnect to an existing streaming response. Returns null if no active stream exists for the specified chat session.
Close the chat transport
close(options?: CloseOptions): Promise<void>Close the underlying ClientTransport, releasing all resources. Delegates to ClientTransport.close(); pass { cancel } to publish a cancel before tearing down. When the ChatTransportProvider owns the lifecycle, it calls this automatically on unmount.
Streaming flag
streaming: booleanRead-only flag indicating whether an own-turn stream is currently being consumed by useChat. Used internally by useMessageSync to gate setMessages calls during active streams.
Subscribe to streaming-state changes
onStreamingChange(callback: (streaming: boolean) => void): () => voidSubscribe to transitions between streaming and idle. The callback fires with true when an own-turn stream starts and false when it ends. Returns an unsubscribe function. Used by useMessageSync to coordinate message-state writes with the streaming gate.
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import * as Ably from 'ably';
import { createClientTransport, createChatTransport } from '@ably/ai-transport/vercel';
import { useChat } from '@ai-sdk/react';
const ably = new Ably.Realtime({ authUrl: '/auth' });
const channel = ably.channels.get('conversation-42');
const clientTransport = createClientTransport({ channel });
const chatTransport = createChatTransport(clientTransport, {
prepareSendMessagesRequest({ chatId, trigger, history, messages, forkOf, parent }) {
return {
body: { chatId, trigger, history, messages, forkOf, parent, locale: 'en-GB' },
headers: { 'x-tenant-id': tenantId },
};
},
});
// In a React component:
const { messages, sendMessage, stop } = useChat({
id: 'conversation-42',
transport: chatTransport,
});