Message
The layout shell for a chat message row – an avatar beside a content column. The align prop flips between received and sent.
Playground
<Message align="end">
<MessageContent>
<Bubble>
<BubbleContent>It's a one-line change – shipping now.</BubbleContent>
</Bubble>
<MessageFooter>Delivered</MessageFooter>
</MessageContent>
</Message>Preview
Compose a row from MessageAvatar and MessageContent, with a Bubble as the body and optional MessageHeader and MessageFooter lines around it.
<Message>
<MessageAvatar>
<Avatar className="size-8">
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
</MessageAvatar>
<MessageContent>
<MessageHeader>Olivia</MessageHeader>
<Bubble variant="secondary">
<BubbleContent>How can I help you today?</BubbleContent>
</Bubble>
<MessageFooter>Read · Yesterday</MessageFooter>
</MessageContent>
</Message>Installation
npx shadcn@latest add https://espresso-base-ui.vercel.app/r/message.jsonUsage
import {
Message,
MessageAvatar,
MessageContent,
MessageFooter,
MessageGroup,
MessageHeader,
} from "@/components/ui/message"<Message align="end">
<MessageContent>
<Bubble>
<BubbleContent>Shipping now.</BubbleContent>
</Bubble>
</MessageContent>
</Message>Alignment
align="start" (the default) lays out a received message; align="end" mirrors the row for sent messages – the content right-aligns and the footer follows it.
<Message>
<MessageContent>
<Bubble variant="secondary">
<BubbleContent>Did you get a chance to review it?</BubbleContent>
</Bubble>
</MessageContent>
</Message>
<Message align="end">
<MessageContent>
<Bubble>
<BubbleContent>It's a one-line change – shipping now.</BubbleContent>
</Bubble>
<MessageFooter>
<CheckCheckIcon className="size-3.5" /> Delivered
</MessageFooter>
</MessageContent>
</Message>Grouped messages
Wrap consecutive messages from the same sender in MessageGroup; leave an empty MessageAvatar on the follow-ups so the bubbles stay column-aligned without repeating the avatar.
<MessageGroup>
<Message>
<MessageAvatar>
<Avatar className="size-8">
<AvatarFallback>SC</AvatarFallback>
</Avatar>
</MessageAvatar>
<MessageContent>
<MessageHeader>Sarah Chen</MessageHeader>
<Bubble variant="secondary">
<BubbleContent>Hey! Are we still on for 3pm?</BubbleContent>
</Bubble>
</MessageContent>
</Message>
<Message>
<MessageAvatar />
<MessageContent>
<Bubble variant="secondary">
<BubbleContent>I'll bring the design mocks.</BubbleContent>
</Bubble>
</MessageContent>
</Message>
</MessageGroup>API reference
Every part renders a div and accepts className plus standard div props. Only the Message root has a prop of its own.
Message
| Prop | Type | Default | Description |
|---|---|---|---|
| align | "start" | "end" | "start" | Row direction – start for received messages (avatar leading), end for sent messages (row reversed, content right-aligned). |
| Component | Description |
|---|---|
| MessageGroup | Vertical stack for consecutive messages from one sender (data-slot="message-group"). |
| MessageAvatar | Rounded avatar slot aligned to the bottom of the row (data-slot="message-avatar"). Reserves min-w-8, so an empty one keeps grouped bubbles aligned; it shifts up automatically when the message has a footer. |
| MessageContent | Column holding header, bubble and footer (data-slot="message-content"). In an end-aligned message its direct slotted children self-align to the right. |
| MessageHeader | Sender name line above the bubble (data-slot="message-header"). Horizontal padding drops to zero next to ghost bubbles. |
| MessageFooter | Meta line below the bubble – timestamps, delivery state or actions (data-slot="message-footer"). Right-aligns in end-aligned messages. |
Styling hooks
The root exposes data-slot="message" and reflects its alignment as data-align; the other parts carry their own data-slot attributes. The internal styles key off these – for example the avatar lifts by -translate-y-8 when a data-slot="message-footer" is present – and you can target the same attributes from CSS for app-level overrides.