# 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] ``` ## 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] ```