---
title: Vue
description: Render streaming Markdown with the Smoothstream Vue 3 component, including Nuxt, SSR, and template class bindings.
---

`@smoothstream/vue` is the Vue 3 adapter. It drives the shared engine through Vue's lifecycle and turns presentation snapshots into keyed VNodes.

<CodeGroup>
```bash title="npm" hideLanguageIcon
npm install @smoothstream/vue
```

```bash title="pnpm" hideLanguageIcon
pnpm add @smoothstream/vue
```

```bash title="yarn" hideLanguageIcon
yarn add @smoothstream/vue
```

```bash title="bun" hideLanguageIcon
bun add @smoothstream/vue
```
</CodeGroup>

Peer dependency: `vue` 3.5 or later. Reveal CSS and the default prose theme import automatically. The same component works in Vue SSR and Nuxt; you do not need a Nuxt module.

## Bind the markdown prop

Vue uses an explicit `markdown` prop instead of slot children. Refs used in the template unwrap as usual.

```vue title="AssistantMessage.vue"
<script setup lang="ts">
import { Smoothstream } from "@smoothstream/vue";

defineProps<{
  text: string;
  receiving: boolean;
}>();
</script>

<template>
  <Smoothstream
    class="assistant-markdown"
    :markdown="text"
    :receiving="receiving"
  />
</template>
```

`inheritAttrs` is false, but fallthrough attributes such as `class` and `style` are merged onto the Markdown root. In templates, multi-word props use kebab-case (`:code-highlighter`, `:reduced-motion`).

<Callout type="tip" title="Follow the streaming contract">
  The usage rules in [Streaming a response](/get-started/streaming) apply here: accumulated snapshots, `receiving` while the model is still writing, and a new `key` for a different answer.
</Callout>

## Chat messages

```vue
<template>
  <Smoothstream
    v-for="message in history"
    :key="message.id"
    :markdown="message.content"
    mode="static"
  />
  <Smoothstream
    :key="active.id"
    :markdown="active.content"
    :receiving="active.receiving"
  />
</template>
```

When `receiving` becomes `false`, leave that streaming instance mounted until presentation finishes.

## SSR and Nuxt

`mode="static"` emits settled semantic HTML on the server and hydrates that markup in place.

In streaming mode with `reducedMotion="system"` (the default), the server and first hydration share an empty motion-pending shell. The browser then reads `prefers-reduced-motion` before Markdown appears. Forced `"always"` and `"never"` policies are deterministic during SSR.

Image loading, syntax highlighting, and clipboard copy begin after mount.

## Timing props reset the session

Changing `interval`, `duration`, `mode`, or `reveal` rebuilds the underlying session. Set them per response rather than updating them while a stream is in flight.

Full option list: [API](/reference/api).
