Message

Message

The layout shell for a chat message row – an avatar beside a content column. The align prop flips between received and sent.

Playground

It's a one-line change – shipping now.
Delivered
message
align
footer
<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.

CN
Olivia
How can I help you today?
Read · Yesterday
<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.json

Usage

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.

Did you get a chance to review it?
It's a one-line change – shipping now.
Delivered
<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.

SC
Sarah Chen
Hey! Are we still on for 3pm?
I'll bring the design mocks.
<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

PropTypeDefaultDescription
align"start" | "end""start"Row direction – start for received messages (avatar leading), end for sent messages (row reversed, content right-aligned).
ComponentDescription
MessageGroupVertical stack for consecutive messages from one sender (data-slot="message-group").
MessageAvatarRounded 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.
MessageContentColumn holding header, bubble and footer (data-slot="message-content"). In an end-aligned message its direct slotted children self-align to the right.
MessageHeaderSender name line above the bubble (data-slot="message-header"). Horizontal padding drops to zero next to ghost bubbles.
MessageFooterMeta 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.

Search documentation

Search the component docs