<script setup lang="ts">
import { Response } from '@/components/elevenlabs-ui/response'
import { onMounted, onUnmounted, ref } from 'vue'
const tokens = [
'### Welcome',
'\n\n',
'This',
' is',
' a',
' **rich',
' markdown',
'**',
' showcase',
' with',
' multiple',
' features.',
'\n\n',
'---',
'\n\n',
'## Data Table',
'\n\n',
'| Name',
' | Role',
' | Status',
' |',
'\n',
'|------|------|--------|',
'\n',
'| Alice',
' | Engineer',
' | Active',
' |',
'\n',
'| Bob',
' | Designer',
' | Active',
' |',
'\n',
'| Carol',
' | PM',
' | Active',
' |',
'\n\n',
'## Inspiration',
'\n\n',
'> *Simplicity',
' is',
' the',
' ultimate',
' sophistication.*',
'\n',
'> —',
' Leonardo',
' da',
' Vinci',
'\n\n',
'## Inline',
' and',
' Block',
' Code',
'\n\n',
'Use',
' `let',
' total',
' =',
' items.length`',
' to',
' count',
' elements.',
'\n\n',
'```',
'python',
'\n',
'def',
' greet(name):',
'\n',
' return',
' f"Hello, {name}!"',
'\n',
'print(greet("World"))',
'\n',
'```',
'\n\n',
'## Math',
'\n\n',
'Inline',
' math:',
' $a^2',
' +',
' b^2',
' =',
' c^2$',
'.',
'\n\n',
'Displayed',
' equation:',
'\n\n',
'$$',
'\n',
'\\int_0^1',
' x^2',
' dx',
' =',
' \\frac{1}{3}',
'\n',
'$$',
'\n\n',
]
const content = ref('')
let intervalId: ReturnType<typeof setInterval>
onMounted(() => {
let index = 0
intervalId = setInterval(() => {
if (index < tokens.length) {
content.value += tokens[index]
index++
}
else {
clearInterval(intervalId)
}
}, 100)
})
onUnmounted(() => {
clearInterval(intervalId)
})
</script>
<template>
<div class="h-full min-h-0 w-full overflow-hidden">
<Response :content="content" class="h-full overflow-auto p-10" />
</div>
</template>Installation
pnpm dlx elevenlabs-ui-vue@latest add response
Usage
import { Response } from "@/components/elevenlabs-ui/response"Basic Usage
<Response>This is a simple text response.</Response>With Markdown
The Response component supports full markdown rendering:
<script setup lang="ts">
const content = `# Heading
This is a paragraph with **bold** and *italic* text.
- List item 1
- List item 2
- List item 3
\`\`\`javascript
const greeting = "Hello, world!"
console.log(greeting)
\`\`\`
`
</script>
<template>
<Response> :content="content" />
</template>Streaming Response
Perfect for streaming AI responses character-by-character:
<script setup lang="ts">
const response = ref('')
// As tokens arrive, append to response
const handleStream = (token: string) => {
response.value += token
}
</script>
<template>
<Response :content="response" />
</template>With Message Component
import { Message, MessageAvatar, MessageContent } from "@/components/elevenlabs-ui/message"
import { Response } from "@/components/elevenlabs-ui/response"
interface Props {
streamingResponse: string
}
defineProps<Props>()
</script>
<template>
<Message from="assistant">
<MessageAvatar src="/ai-avatar.jpg" name="AI" />
<MessageContent>
<Response>{{ streamingResponse }}</Response>
</MessageContent>
</Message>
</template>API Reference
Response
A memoized wrapper around vue-stream-markdown that renders streaming markdown with smooth animations.
Props
Extends all props from the vue-stream-markdown component.
| Prop | Type | Description |
|---|---|---|
| content | string | Content to render (markdown) |
| class | string | Optional CSS classes |
| ...props | vue-stream-markdown | All vue-stream-markdown component props |
Notes
- Built on top of
vue-stream-markdownfor smooth markdown streaming animations - Automatically removes top margin from first child and bottom margin from last child for clean integration
- Memoized to prevent unnecessary re-renders - only updates when children change
- Supports full markdown syntax including code blocks, lists, tables, and more
- Optimized for streaming AI responses with character-by-character rendering
- Works seamlessly with the Message component
- This component is inspired by Vercel's AI SDK Response component with modifications for ElevenLabs UI