How do I create an agent?
<script setup lang="ts">
import { Message, MessageContent } from '@/components/elevenlabs-ui/message'
import { Orb } from '@/components/elevenlabs-ui/orb'
import { Response } from '@/components/elevenlabs-ui/response'
import { onMounted, onUnmounted, ref } from 'vue'
const assistantMessageTokens = [
'To',
' create',
' a',
' new',
' agent',
' with',
' **',
'ElevenLabs',
' Agents',
'**',
',',
' head',
' to',
' this',
' link',
':',
' ',
'[',
'https://elevenlabs.io/app/agents',
'](',
'https://elevenlabs.io/app/agents',
')',
'.',
'\n\n',
'1.',
' Sign',
' in',
' to',
' your',
' ElevenLabs',
' account',
'.',
'\n',
'2.',
' Click',
' **New',
' Agent**',
' to',
' start',
'.',
'\n',
'3.',
' Give',
' your',
' agent',
' a',
' name',
' and',
' description',
'.',
'\n',
'4.',
' Configure',
' its',
' behavior',
',',
' knowledge',
' sources',
',',
' and',
' voice',
'.',
'\n',
'5.',
' Save',
' it',
' —',
' and',
' your',
' agent',
' is',
' ready',
' to',
' use',
'.',
]
const content = ref('\u200B')
const isStreaming = ref(false)
let intervalId: ReturnType<typeof setInterval>
let timeoutId: ReturnType<typeof setTimeout>
onMounted(() => {
let currentContent = ''
let index = 0
// Equivalent to the 500ms delay before "talking" state
timeoutId = setTimeout(() => {
isStreaming.value = true
}, 500)
// Streaming interval logic
intervalId = setInterval(() => {
if (index < assistantMessageTokens.length) {
currentContent += assistantMessageTokens[index]
content.value = currentContent
index++
}
else {
clearInterval(intervalId)
isStreaming.value = false
}
}, 100)
})
onUnmounted(() => {
if (intervalId)
clearInterval(intervalId)
if (timeoutId)
clearTimeout(timeoutId)
})
</script>
<template>
<div class="flex h-full max-h-[400px] w-full max-w-2xl flex-col overflow-hidden">
<div class="flex flex-col gap-4 overflow-y-auto px-4 py-4">
<div class="shrink-0">
<Message from="user">
<MessageContent>
How do I create an agent?
<!-- <Response :content="'How do I create an agent?'" /> -->
</MessageContent>
</Message>
</div>
<div class="message-demo-lists shrink-0">
<Message from="assistant">
<MessageContent>
<Response :content="content" />
</MessageContent>
<div class="ring-border size-8 overflow-hidden rounded-full ring-1">
<Orb
class="h-full w-full"
:agent-state="isStreaming ? 'talking' : null"
/>
</div>
</Message>
</div>
</div>
</div>
</template>
<style scoped>
/* Scoped styles replace the 'style jsx global' logic */
:deep(.message-demo-lists ol),
:deep(.message-demo-lists ul) {
padding-left: 1.25rem !important;
}
:deep(.message-demo-lists li) {
margin-left: 0 !important;
}
</style>Installation
pnpm dlx elevenlabs-ui-vue@latest add message
Usage
import { Message, MessageAvatar, MessageContent } from "@/components/elevenlabs-ui/message"Basic Message
<template>
<Message from="user">
<MessageAvatar src="/user-avatar.jpg" name="John" />
<MessageContent>
Hello, how can I help you?
</MessageContent>
</Message>
<Message from="assistant">
<MessageAvatar src="/assistant-avatar.jpg" name="AI" />
<MessageContent>
I'm here to assist you with any questions!
</MessageContent>
</Message>
</template>Message Variants
The MessageContent component supports two variants:
<script setup lang="ts">
import { Message, MessageAvatar, MessageContent } from "@/components/elevenlabs-ui/message"
</script>
<template>
<!-- Contained variant - default, has background and padding -->
<Message from="user">
<MessageAvatar src="/user-avatar.jpg" />
<MessageContent variant="contained">
This is a contained message with background
</MessageContent>
</Message>
<!-- Flat variant - no background for assistant, minimal styling -->
<Message from="assistant">
<MessageAvatar src="/assistant-avatar.jpg" />
<MessageContent variant="flat">
This is a flat message with minimal styling
</MessageContent>
</Message>
</template>In a Conversation
<script>
import { Conversation, ConversationContent } from "@/components/elevenlabs-ui/conversation"
import { Message, MessageAvatar, MessageContent } from "@/components/elevenlabs-ui/message"
</script>
<template>
<Conversation>
<ConversationContent>
<Message
v-for="message in messages"
:key="message.id"
:from="message.from"
>
<MessageAvatar
:src="message.avatarUrl"
:name="message.name"
/>
<MessageContent>
{{ message.content }}
</MessageContent>
</Message>
</ConversationContent>
</Conversation>
</template>API Reference
Message
The main container component that handles layout and alignment based on message sender.
Props
| Prop | Type | Description |
|---|---|---|
| from | "user" | "assistant" | Required. Determines alignment and styling |
| class | string | Optional CSS classes |
| ...props | HTMLAttributes | All standard div element props |
MessageContent
Container for message text and content with variant styling.
Props
| Prop | Type | Description |
|---|---|---|
| variant | "contained" | "flat" | Visual style variant (default: "contained") |
| class | string | Optional CSS classes |
| ...props | HTMLAttributes | All standard div element props |
MessageAvatar
Avatar component for displaying user or assistant profile images.
Props
| Prop | Type | Description |
|---|---|---|
| src | string | Required. Avatar image URL |
| name | string | Name for fallback (shows first 2 chars if no image) |
| class | string | Optional CSS classes |
| ...props | AvatarProps | All standard Avatar component props |
Notes
- Uses CSS group selectors for context-aware styling based on
fromprop - User messages align to the right, assistant messages to the left
- Contained variant provides background colors that differ for user/assistant
- Flat variant is useful for assistant messages in a minimal design
- Avatar has a subtle ring border and fallback text support
- Works seamlessly with the Conversation component
- This component is inspired by Vercel's AI SDK Message component with modifications for ElevenLabs UI