Quickstart
Build a streaming Nuxt chat with Vue, assistant-ui, and the AI SDK.
This guide adds a streaming chat to a Nuxt app in about five minutes. The runtime stays in a client-only component and the model call stays in a Nitro route.
Install the runtime
Install the Vue binding, the AI SDK runtime, and an AI SDK provider:
pnpm add @assistant-ui/vue @assistant-ui/ai-sdk ai @ai-sdk/openai reactreact is the AI SDK runtime's substrate — an optional peer of @assistant-ui/ai-sdk, so it does not install on its own. For nuxi typecheck, add @types/react as a dev dependency: a type-only react reference rides through the core runtime types.
pnpm add -D @types/reactAdd your provider key to .env:
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Install the styled components
Add the Vue assistant-ui registry once in components.json:
{
"registries": {
"@assistant-ui": "https://r.assistant-ui.com/vue/{name}.json"
}
}Install the chat surface:
npx shadcn@latest add @assistant-ui/thread @assistant-ui/thread-listThis writes Vue components under components/assistant-ui. The registry installs their assistant-ui, Vue, and UI dependencies.
Create the assistant client
Use a .client.vue file so the runtime is created only in the browser:
<script setup lang="ts">
import { AuiConfig, AuiProvider } from "@assistant-ui/vue";
import { AISDKChat } from "@assistant-ui/ai-sdk";
import Thread from "~/components/assistant-ui/thread.vue";
const config = AuiConfig({
threads: AISDKChat(),
});
</script>
<template>
<AuiProvider :config="config">
<Thread class="h-dvh" />
</AuiProvider>
</template>AISDKChat() creates one streaming thread. Its default transport sends requests to /api/chat.
Add the streaming route
Create the Nitro route that receives UI messages and returns an AI SDK UI message stream:
import { openai } from "@ai-sdk/openai";
import { convertToModelMessages, streamText, type UIMessage } from "ai";
export default defineEventHandler(async (event) => {
const { messages, system } = await readBody<{
messages: UIMessage[];
system?: string;
}>(event);
const result = streamText({
model: openai("gpt-5.6-luna"),
messages: await convertToModelMessages(messages),
system,
});
return result.toUIMessageStreamResponse();
});Render the assistant
Nuxt recognizes the .client.vue suffix and only mounts this component in the browser:
<template>
<Assistant />
</template>Start the app with pnpm dev, then send a message. The response streams from server/api/chat.post.ts into the thread.
Next steps
Use AISDKThreads when the chat needs a thread list, server rendering to understand the .client.vue boundary, and Tool UI to render tool calls.