Message
Displays a message in a conversation, with optional avatar, header, footer, and alignment.
Demo
The Message component lays out a single message in a conversation. It handles the avatar, alignment, header, and footer around the message surface.
For AI apps, you can render reasoning steps, tool calls and assistant messages using the Message component.
Avatar
Use MessageAvatar to render an avatar next to the message. Set align="end" on the message to align the avatar to the end of the message.
Group
Use MessageGroup to stack consecutive messages from the same sender. Render an empty MessageAvatar on the earlier messages to keep them aligned with the avatar on the last one.
Actions
Place message-level actions in MessageFooter, such as copy, retry, or feedback buttons.
Attachment
Render an Attachment as a sibling of the Bubble inside MessageContent, above it or below it. It keeps its own card surface instead of sitting inside the message surface.
Anatomy
Import all parts and piece them together.
<script setup>
import {
Bubble,
Message,
MessageAvatar,
MessageContent,
MessageFooter,
MessageHeader,
} from "@/components/ui/message";
</script>
<template>
<Message>
<MessageAvatar />
<MessageContent>
<MessageHeader />
<Bubble />
<MessageFooter />
</MessageContent>
</Message>
</template>API Reference
Message
MessageGroup
MessageAvatar
MessageContent
MessageHeader
MessageFooter
Accessibility
Keyboard shortcuts and ARIA behavior.
- Message is a presentational layout wrapper. Accessibility comes from the content you place inside it.
- Action buttons in MessageFooter are usually icon-only, so give each one an aria-label. Add a title as well when the label is worth showing on hover.
- For in-progress messages, use a Marker with role="status" so assistive tech announces the update as it appears.
- Each part sets its own data-slot (message, message-group, message-avatar, message-content, message-header, message-footer), and Message adds data-align. Those attributes are the styling hooks: MessageContent reads the Bubble's data-variant through has-[[data-slot=bubble][data-variant=ghost]]:gap-0, and MessageFooter reads the row alignment through group/message.