# useView
`useView` subscribes to a session's default view and returns the visible messages, branch navigation, write operations, and pagination state. It is the primary hook for rendering a conversation UI.
By default the hook subscribes to the nearest [`ClientSessionProvider`](https://ably.com/docs/ai-transport/api/react/core/providers.md#client-session-provider)'s default view. Pass `session` to use a different session's default view, or `view` to subscribe to a specific view created with [`useCreateView`](https://ably.com/docs/ai-transport/api/react/core/use-create-view.md) or [`session.createView()`](https://ably.com/docs/ai-transport/api/javascript/core/client-session.md#create-view).
#### Javascript
```
import { useView } from '@ably/ai-transport/react';
function Conversation() {
const { messages, send } = useView({ limit: 30 });
return (
<>
{messages.map(({ codecMessageId, message }) => (
))}
send({ kind: 'user-message', message: { role: 'user', parts: [{ type: 'text', text }] } })
}
/>
>
);
}
```
This hook must be used within a [`ClientSessionProvider`](https://ably.com/docs/ai-transport/api/react/core/providers.md#client-session-provider) unless `session` or `view` is supplied explicitly.
## Parameters
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| session | optional | A client session whose default view to subscribe to. Defaults to the nearest provider. | `ClientSession` |
| view | optional | A specific view to subscribe to directly. Takes priority over `session`. | `View` |
| limit | optional | Maximum number of older Runs to reveal per page. When provided, auto-loads the first page on mount. | Number |
| skip | optional | When `true`, skip all subscriptions and return an empty handle immediately. | Boolean |
## Returns
| Property | Description | Type |
| --- | --- | --- |
| messages | The visible messages along the selected branch, each paired with its `codecMessageId`. Read the domain object from each entry's `message` field. | `CodecMessage[]` |
| hasOlder | Whether there are older Runs that can be revealed via `loadOlder`. | Boolean |
| loading | Whether a page load is currently in progress. | Boolean |
| loadError | Set when the most recent `loadOlder` call failed. Cleared automatically on the next successful load. | `Ably.ErrorInfo` or Undefined |
| loadOlder | Reveal older Runs. No-op if already loading. | `() => Promise` |
| runOf | Look up the `RunInfo` for the Run that owns the given `codecMessageId`. |
|
| run | Direct lookup by Run id. |
|
| runs | Snapshot of the visible Runs along the selected branch, in chronological order. Returns `[]` when the view isn't resolved. | `() => RunInfo[]` |
| branchSelection | Resolve the `BranchSelection` bundle anchored at `codecMessageId`. Always returns a safe object. |
|
| selectSibling | Select a sibling at the branch point anchored at `codecMessageId`. | `(codecMessageId, index) => void` |
| send | Send one or more `TInput`s on the channel and fire a POST. Wrap a domain message via `codec.createUserMessage` (or build the `{ kind: 'user-message', message }` literal) to send a fresh user message. Takes optional
. | `(events, options?) => Promise` |
| regenerate | Regenerate an assistant message using this view's branch for history. | `(messageId, options?) => Promise` |
| edit | Edit a user message, forking from this view's branch. | `(messageId, inputs, options?) => Promise` |
| Property | Description | Type |
| --- | --- | --- |
| runId | The Run's unique identifier. | String |
| clientId | Identity of the Ably client that started this Run. Empty string when the wire didn't carry an owner client id. | String |
| status | Run lifecycle status. `'active'` while streaming, `'suspended'` while paused awaiting input, otherwise the `RunEndReason` the Run terminated with. | `'active' \| 'suspended' \| RunEndReason` |
| invocationId | The agent-minted `invocationId` observed for this Run, adopted from `ai-run-start`. Empty string until run-start arrives, or if the wire didn't carry an invocation-id. | String |
| Property | Description | Type |
| --- | --- | --- |
| hasSiblings | True when the anchor has more than one sibling. | Boolean |
| siblings | The selected sibling and any alternatives in tree-order. Always contains the currently rendered message for known ids. | `TMessage[]` |
| index | Index of the selected sibling within `siblings`. `0` when there is no real branching. | Number |
| selected | Convenience reference to `siblings[index]`. `undefined` only when `siblings` is empty. | `TMessage` or Undefined |
| Property | Description | Type |
| --- | --- | --- |
| forkOf | The codec-message-id of the message this send replaces (fork). | String |
| parent | The codec-message-id of the predecessor in the conversation thread. Auto-computed when omitted. | String |
| runId | Reuse an existing `runId` (for example to resume a suspended run). | String |
| inputEventId | Override the `inputEventId` for this send. Defaults to `crypto.randomUUID()`. | String |
## Reveal older Runs
`loadOlder(): Promise`
Load older messages into the view by revealing more Runs. When `limit` is set on the hook, the first page auto-loads on mount. Call `loadOlder` again to reveal more. The call is gated so concurrent invocations collapse to one in-flight request.
On failure, `loadError` is set. On the next successful load, `loadError` is cleared automatically.
## Look up a Run by message id
`runOf(codecMessageId: string): RunInfo | undefined`
Look up the [`RunInfo`](#returns) for the Run that owns the given `codecMessageId`. Returns `undefined` when the codec-message-id has not been observed.
## Look up a Run by id
`run(runId: string): RunInfo | undefined`
Direct lookup by Run id. Symmetric with [`runOf`](#run-of) for callers that already hold a `runId`.
## Resolve a branch selection
`branchSelection(codecMessageId: string): BranchSelection`
Resolve the `BranchSelection` bundle anchored at `codecMessageId`. Always returns a safe object: for branch anchors with N siblings, `siblings` carries every sibling Run's view of the anchor slot; for non-anchor messages, `siblings` is `[thisMessage]` and `hasSiblings` is `false`.
## Select a sibling
`selectSibling(codecMessageId: string, index: number): void`
Select a sibling at the branch point anchored at `codecMessageId`. `index` is clamped to `[0, siblings.length - 1]`. Silent no-op when the message is not a branch anchor. Emits `'update'` on the underlying view when the visible output changes.
## Send inputs
`send(events: TInput | TInput[], options?: SendOptions): Promise`
Send one or more `TInput`s on the channel and fire a POST. Each `TInput` carries its own routing metadata (`parent`, `target`, `codecMessageId`).
To send a fresh user message, build a `UserMessage` input. Use the codec factory (`codec.createUserMessage(message)`) or build the literal directly: `{ kind: 'user-message', message }`. A send containing at least one `UserMessage` mints a fresh Run. A send containing only tool-resolution inputs (`tool-result`, `tool-result-error`, `tool-approval-response`) is a continuation; pair it with `options.runId` to extend a suspended Run.
## Regenerate an assistant message
`regenerate(messageId: string, options?: SendOptions): Promise`
Regenerate an assistant message. Creates a new Run that targets the message and threads under its parent user message. Both ids are computed automatically from this view's branch.
## Edit a user message
`edit(messageId: string, inputs: TInput | TInput[], options?: SendOptions): Promise`
Edit a user message. Creates a new Run that forks the target message with the replacement inputs. `forkOf`, `parent`, and history are computed automatically from this view's branch.
## Example
A conversation component that loads older messages on mount, renders branch navigation when a sibling is available, and offers a regenerate button on each assistant turn.
### Javascript
```
import { useView } from '@ably/ai-transport/react';
function Conversation() {
const {
messages,
hasOlder,
loadOlder,
branchSelection,
selectSibling,
send,
regenerate,
} = useView({ limit: 30 });
return (
<>
{hasOlder && }
{messages.map(({ codecMessageId, message }) => {
const branch = branchSelection(codecMessageId);
return (
);
})}
send({ kind: 'user-message', message: { role: 'user', parts: [{ type: 'text', text }] } })
}
/>
>
);
}
```
## Related Topics
- [Providers](https://ably.com/docs/ai-transport/api/react/core/providers.md): API reference for the AI Transport React providers: ClientSessionProvider and the createSessionHooks factory.
- [useClientSession](https://ably.com/docs/ai-transport/api/react/core/use-client-session.md): Read a ClientSession from the nearest ClientSessionProvider in the AI Transport React integration.
- [useCreateView](https://ably.com/docs/ai-transport/api/react/core/use-create-view.md): Create an independent View over the AI Transport conversation tree from React, with its own branch selections and pagination.
- [useTree](https://ably.com/docs/ai-transport/api/react/core/use-tree.md): Stable structural query callbacks for the AI Transport conversation tree from React.
- [useAblyMessages](https://ably.com/docs/ai-transport/api/react/core/use-ably-messages.md): Subscribe to raw Ably InboundMessages on the AI Transport channel 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.