# ChatTransportProvider `ChatTransportProvider` is the entry point for the Vercel React integration. It wraps children in a `ClientSessionProvider` bound to `UIMessageCodec`, constructs a [`ChatTransport`](https://ably.com/docs/ai-transport/api/javascript/vercel/chat-transport.md) over that session, and exposes both through React context. Descendants call [`useChatTransport`](https://ably.com/docs/ai-transport/api/react/vercel/use-chat-transport.md) to get the transport (and the session) for Vercel `useChat`. The Realtime client is read from the surrounding ``. The session is created once on first render. The chat transport is recreated only when `chatOptions` changes. #### Javascript ``` import * as Ably from 'ably'; import { AblyProvider } from 'ably/react'; import { ChatTransportProvider } from '@ably/ai-transport/vercel/react'; const ably = new Ably.Realtime({ authUrl: '/api/auth/token' }); function App() { return ( ); } ``` `ChatTransportProvider` also re-exports the Vercel-baked core hooks (`useClientSession`, `useView`, `useTree`, `useCreateView`, `useAblyMessages`, and the underlying `ClientSessionProvider`) from the same entry point, all pre-bound to the Vercel `TInput` / `TOutput` / `TProjection` / `TMessage` types. ## Props `ChatTransportProviderProps` extends [`ClientSessionProviderProps`](https://ably.com/docs/ai-transport/api/react/core/providers.md#client-session-provider-props) with the `codec` field omitted (always `UIMessageCodec`) and adds four transport-owned options for the agent-invocation POST. | Property | Description | Type | | --- | --- | --- | | channelName | The channel the session subscribes to. Used as the registry key for nested providers. | String | | api | Endpoint the chat transport POSTs the invocation to, to wake the agent. Defaults to `/api/chat`. | String | | credentials | Fetch credentials mode for the invocation POST. Set to `'include'` for cookie-based cross-origin auth. | `RequestCredentials` | | fetch | Custom fetch implementation for the invocation POST. Defaults to `globalThis.fetch`. | `typeof globalThis.fetch` | | chatOptions | Hooks for customising chat request construction (for example `prepareSendMessagesRequest`). Must be stable across renders; wrap in `useMemo` or define outside the component. A new object reference recreates the `ChatTransport`. |
| | clientId | The client's identity, used as the Ably publisher `clientId` on everything the session publishes. | String | | messages | Initial messages to seed the conversation tree with. | `UIMessage[]` | | logger | Logger instance for diagnostic output. | `Logger` | | children | Descendant components that consume the chat transport via [`useChatTransport`](https://ably.com/docs/ai-transport/api/react/vercel/use-chat-transport.md). | `ReactNode` |
| Property | Description | Type | | --- | --- | --- | | prepareSendMessagesRequest | Hook called before each `sendMessages` request. Returns `{ body?, headers? }` to merge into the agent-invocation POST. The run's invocation identifiers always take precedence over the returned body. | `(context: SendMessagesRequestContext) => { body?, headers? }` |
## Behaviour `useChatTransport` and the re-exported `useClientSession` / `useView` / `useTree` / `useCreateView` / `useAblyMessages` find the nearest provider in the tree. Pass `channelName` to look up a specific provider by name when nesting multiple. The underlying `ClientSession` is created once on first render via `useRef`, and `connect()` runs from a `useEffect`. The session is closed when the provider truly unmounts. The `ChatTransport` itself is not closed on unmount: its `close()` delegates to `ClientSession.close()`, which the inner `ClientSessionProvider` already calls. Auto-closing here would double-close in React Strict Mode. If `createClientSession` throws, the error surfaces via [`useClientSession.sessionError`](https://ably.com/docs/ai-transport/api/react/core/use-client-session.md#returns) and [`useChatTransport.chatTransportError`](https://ably.com/docs/ai-transport/api/react/vercel/use-chat-transport.md). The component tree does not crash. ## Nest providers for multiple sessions Nest providers with distinct `channelName` values to manage more than one chat in the same tree. Each provider merges its slot into the parent record so descendants can address any registered session by name. ### Javascript ``` ``` Inside `App`: ### Javascript ``` import { useChatTransport } from '@ably/ai-transport/vercel/react'; function App() { const main = useChatTransport({ channelName: 'ai:main' }); const aux = useChatTransport({ channelName: 'ai:aux' }); // ... } ``` ## Example Full Vercel chat wiring using `ChatTransportProvider`, `useChatTransport`, and `useChat` from `@ai-sdk/react`. ### Javascript ``` 'use client'; import { useEffect, useState } from 'react'; import * as Ably from 'ably'; import { AblyProvider } from 'ably/react'; import { ChatTransportProvider, useChatTransport } from '@ably/ai-transport/vercel/react'; import { useChat } from '@ai-sdk/react'; function Providers({ children }) { const [client, setClient] = useState(null); useEffect(() => { const ably = new Ably.Realtime({ authUrl: '/api/auth/token', clientId: 'user' }); setClient(ably); return () => ably.close(); }, []); if (!client) return null; return {children}; } function Chat() { const { chatTransport } = useChatTransport(); const { messages, sendMessage, status, stop } = useChat({ transport: chatTransport }); return (
{messages.map((m) => (
{m.role}: {m.parts.map((p) => p.type === 'text' ? p.text : '').join('')}
))} {status === 'streaming' ? : }
); } export default function Page() { return ( ); } ```
## Related Topics - [useChatTransport](https://ably.com/docs/ai-transport/api/react/vercel/use-chat-transport.md): Read a ChatTransport and its underlying ClientSession from the nearest ChatTransportProvider in AI Transport. - [useMessageSync](https://ably.com/docs/ai-transport/api/react/vercel/use-message-sync.md): Wire AI Transport view updates into Vercel useChat's setMessages from React. ## Documentation Index To discover additional Ably documentation: 1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages. 2. Identify relevant URLs from that index. 3. Fetch target pages as needed. Avoid using assumed or outdated documentation paths.