Toggle Sidebar B
AppearanceLight & dark mode D

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.

Dark previewReplay preview
Me
Deploying to prod real quick.
Rabbit
It's 4:55 PM. On a Friday.
Me
It's a one-line change.
Rabbit
It's always a one-line change 😭.
Alright, let me take a look.
👍
Oliver is typing...

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.

Dark previewReplay preview
Rabbit
The build failed during dependency installation.
Me
Can you share the exact error?
Rabbit
Here's the error from the logs
Something went wrong with the build. The libraries are not installed correctly. Try running the build again.

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.

Dark previewReplay preview
I checked the registry addresses.
Rabbit
The component and example JSON now live under the UI registry.

Actions

Place message-level actions in MessageFooter, such as copy, retry, or feedback buttons.

Dark previewReplay preview
The install failure is coming from the workspace package.
Okay drop me a link. Taking a look...

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.

Dark previewReplay preview
Workspace
Here's the image. Can you add it to the PDF? Use it for the cover page.
Done. Here's the PDF with the image added as the cover page.
sales-dashboard.pdfPDF · 2.4 MB
Thanks. Looks good.

Anatomy

Import all parts and piece them together.

vue
<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

PropTypeDefaultDescription
align"start" | "end""start"The alignment of the message in the conversation. end reverses the row and sets data-align on the wrapper, which the footer and the content both read.
classstring—Additional classes to apply to the row, merged with cn().
SlotDescription
defaultMessageAvatar and MessageContent.

MessageGroup

PropTypeDefaultDescription
classstring—Additional classes to apply to the group root, merged with cn().
SlotDescription
defaultConsecutive Message rows from one sender.

MessageAvatar

PropTypeDefaultDescription
classstring—Additional classes to apply to the avatar slot, merged with cn().
SlotDescription
defaultAvatar image, initials, or icon.

MessageContent

PropTypeDefaultDescription
classstring—Additional classes to apply to the content slot, merged with cn().
SlotDescription
defaultHeader, message surface, and footer.

MessageHeader

PropTypeDefaultDescription
classstring—Additional classes to apply to the header, merged with cn().
SlotDescription
defaultSender name and metadata.

MessageFooter

PropTypeDefaultDescription
classstring—Additional classes to apply to the footer, merged with cn().
SlotDescription
defaultTimestamp, delivery status, or action buttons.

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.