# Server rendering
URL: /docs/vue/ssr

Keep Vue assistant state in a client-only Nuxt component and stream from Nitro.

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

Place the `AuiProvider` and its runtime in a `.client.vue` component. This is required even when the surrounding Nuxt page is server-rendered.

An assistant runtime owns a client tree and reactive scopes. If it renders on the server, each request creates a client tree that Vue SSR never disposes. That leaks one assistant tree per request. The `.client.vue` boundary prevents the provider, its runtime, and its scopes from being created during server rendering.

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

## What belongs on the server

Keep provider credentials, `streamText`, and the streaming response in a Nitro route. Nitro runs `server/api/chat.post.ts` on the server, while the browser receives only the 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();
});
```

## Nuxt wiring

Server-rendered pages can include the client component normally. Nuxt resolves the `.client.vue` suffix and mounts it after hydration.

```
<template>
  <main>
    <Assistant />
  </main>
</template>
```

Keep only page data and ordinary server-renderable UI outside the boundary. Do not create `AuiConfig`, `AISDKChat`, `AISDKThreads`, or an `AuiProvider` in `app.vue`, a page setup block that runs during SSR, or a Nitro route.