Skip to main content

Overview

The ChatMessages component displays a list of chat messages with support for streaming (like AI responses), auto-scrolling, markdown rendering, and customizable user/assistant message styling.

Basic usage

<template>
  <UChatMessages :messages="messages" />
</template>

<script setup lang="ts">
const messages = ref([
  { id: '1', role: 'user', content: 'Hello!' },
  { id: '2', role: 'assistant', content: 'Hi! How can I help you today?' }
])
</script>

With streaming

<template>
  <UChatMessages 
    :messages="messages"
    :status="status"
  />
</template>

<script setup lang="ts">
import { useChat } from 'ai/vue'

const { messages, status } = useChat({
  api: '/api/chat'
})
</script>

Props

messages
UIMessage[]
required
Array of chat messages to display. Each message should have id, role, and content properties.
status
'pending' | 'streaming' | 'done'
default:"'done'"
Current chat status for showing loading indicators.
shouldAutoScroll
boolean
default:"true"
Whether to automatically scroll to the bottom when new messages arrive.
shouldScrollToBottom
boolean
default:"true"
Whether to show a “scroll to bottom” button when scrolled up.
autoScrollButton
ButtonProps
Configuration for the auto-scroll button.
userMessage
object
Custom styling configuration for user messages.
assistantMessage
object
Custom styling configuration for assistant messages.
compact
boolean
default:"false"
Enable compact mode with reduced spacing.
spacingOffset
number
default:"0"
Additional spacing offset from the bottom (useful when combined with sticky prompt).

Message interface

interface UIMessage {
  id: string
  role: 'user' | 'assistant' | 'system'
  content: string
  metadata?: Record<string, any>
}

With Vercel AI SDK

<template>
  <div>
    <UChatMessages
      :messages="messages"
      :status="status"
    />
    <UChatPrompt
      v-model="input"
      :loading="status === 'pending'"
      @submit="handleSubmit"
    />
  </div>
</template>

<script setup lang="ts">
import { useChat } from 'ai/vue'

const { messages, input, status, handleSubmit } = useChat({
  api: '/api/chat'
})
</script>

Custom message styling

<template>
  <UChatMessages
    :messages="messages"
    :user-message="{
      variant: 'solid',
      color: 'primary'
    }"
    :assistant-message="{
      variant: 'soft',
      color: 'neutral'
    }"
  />
</template>

Slots

message
slot
Customize the entire message rendering.
user-message
slot
Customize user messages only.
assistant-message
slot
Customize assistant messages only.
message-actions
slot
Add action buttons to messages (copy, regenerate, etc.).

Build docs developers (and LLMs) love