# Chat Layout
Build AI chat interfaces with message streams, reasoning, tool calling, and Vercel AI SDK integration.
## Component tree
```
UApp
└── NuxtLayout (dashboard)
└── UDashboardGroup
├── UDashboardSidebar (conversations)
└── NuxtPage
└── UDashboardPanel
├── #header → UDashboardNavbar
├── #body → UContainer → UChatMessages
│ ├── #content → UChatReasoning, UChatTool, MDC
│ └── #indicator (loading)
└── #footer → UContainer → UChatPrompt
└── UChatPromptSubmit
```
## Setup
### Install AI SDK
```bash
pnpm add ai @ai-sdk/gateway @ai-sdk/vue
```
### Server endpoint
```ts [server/api/chat.post.ts]
import { streamText, convertToModelMessages } from 'ai'
import { gateway } from '@ai-sdk/gateway'
export default defineEventHandler(async (event) => {
const { messages } = await readBody(event)
return streamText({
model: gateway('anthropic/claude-sonnet-4.6'),
system: 'You are a helpful assistant.',
messages: await convertToModelMessages(messages)
}).toUIMessageStreamResponse()
})
```
## Full page chat
```vue [pages/chat/[id].vue]
{{ part.text }}
```
## Key components
### ChatMessages
Scrollable message list with auto-scroll and loading indicator.
| Prop | Description |
|---|---|
| `messages` | Array of AI SDK messages |
| `status` | `'submitted'`, `'streaming'`, `'ready'`, `'error'` |
Slots: `#content` (receives `{ message }`), `#actions` (per-message), `#indicator` (loading)
### ChatMessage
Individual message bubble with avatar, actions, and slots.
| Prop | Description |
|---|---|
| `message` | AI SDK UIMessage object |
| `side` | `'left'` (default), `'right'` |
### ChatReasoning
Collapsible block for AI reasoning / thinking process. Auto-opens during streaming, auto-closes when done.
| Prop | Description |
|---|---|
| `text` | Reasoning text (displayed inside collapsible content) |
| `streaming` | Whether reasoning is actively streaming |
| `open` | Controlled open state |
Use `isPartStreaming(part)` from `@nuxt/ui/utils/ai` to determine streaming state.
### ChatTool
Collapsible block for AI tool invocation status.
| Prop | Description |
|---|---|
| `text` | Tool status text (displayed in trigger) |
| `icon` | Icon name |
| `loading` | Show loading spinner on icon |
| `streaming` | Whether tool is actively running |
| `suffix` | Secondary text after label |
| `variant` | `'inline'` (default), `'card'` |
| `chevron` | `'trailing'` (default), `'leading'` |
Use `isToolStreaming(part)` from `@nuxt/ui/utils/ai` to determine if a tool is still running.
### ChatShimmer
Text shimmer animation for streaming states. Automatically used by ChatReasoning and ChatTool when streaming.
### ChatPrompt
Enhanced textarea form for prompts. Accepts all Textarea props.
| Prop | Description |
|---|---|
| `v-model` | Input text binding |
| `error` | Error from chat instance |
| `variant` | `'outline'` (default), `'subtle'`, `'soft'`, `'ghost'`, `'none'` |
Slots: `#default` (submit button), `#footer` (below input, e.g. model selector)
### ChatPromptSubmit
Submit button with automatic status handling (send/stop/reload).
### ChatPalette
Layout wrapper for chat inside overlays (Modal, Slideover, Drawer).
## Chat in a modal
```vue
```
## With model selector
```vue
```
## Conversation sidebar
```vue [layouts/dashboard.vue]
```