Message Bubble
The MessageBubble component displays conversational messages in AI and chat interfaces. It’s a compound component — MessageBubble.Root sets the message role, MessageBubble.Content holds the body, MessageBubble.Text / MessageBubble.Markdown render the message, and MessageBubble.Footer carries actions like copy, edit, and timestamps. User and assistant messages get distinct styling and alignment.
Installation
import { MessageBubble, CopyButton, Button, IconV2, Text,} from "@harnessio/ui/components";
// ...
return ( <MessageBubble.Root role="user"> <MessageBubble.Content> <MessageBubble.Text>Your message here</MessageBubble.Text> </MessageBubble.Content> <MessageBubble.Footer> <CopyButton name="Your message here" buttonVariant="ghost" size="sm" /> <Button iconOnly variant="ghost" size="sm" onClick={handleEdit}> <IconV2 name="edit" /> </Button> <Text variant="caption-normal" color="foreground-3"> {formatTime(timestamp)} </Text> </MessageBubble.Footer> </MessageBubble.Root>)Anatomy
MessageBubble is a compound component. Compose the parts inside a Root that declares who the message is from.
<MessageBubble.Root role="assistant"> <MessageBubble.Content> <MessageBubble.Text>Here's the answer.</MessageBubble.Text> </MessageBubble.Content> <MessageBubble.Footer>{/* actions, timestamp */}</MessageBubble.Footer></MessageBubble.Root>MessageBubble.Root— the container.role(user/assistant) is a styling discriminator that drives the bubble’s alignment and appearance; it’s optional, and when omitted neither role style is applied. ExtendsHTMLAttributes<HTMLDivElement>.MessageBubble.Content— the body wrapper that carries the role-based content styling. ExtendsHTMLAttributes<HTMLDivElement>.MessageBubble.Text— renders the message as body text. Accepts the same props asText, plus an optionalspeedfor a typewriter reveal (character-by-character) when the child is a string.MessageBubble.Markdown— renders the message from a markdown string (itschildren) usingMarkdownViewerat the small variant, for assistant replies that contain formatting or code.MessageBubble.Footer— a flexible row for actions (copy, edit), timestamps, or any custom content. ExtendsHTMLAttributes<HTMLDivElement>.
Best practices
Do
- Set
roleon everyRootso user and assistant messages align and read distinctly. - Use
MessageBubble.Markdownfor assistant responses that include lists, code, or links; useMessageBubble.Textfor plain conversational text. - Keep
Footeractions minimal and consistent (e.g. copy + edit + timestamp) so the pattern is predictable across the thread.
Don’t
- Don’t put primary content in the
Footer— it’s for secondary actions and metadata. - Don’t rely on the
rolestyling alone to convey who is speaking in contexts where color/alignment isn’t enough; include an author label or avatar nearby.
Content
- Keep timestamps in the
Footershort and localized (e.g. “2:30 PM”). - For copy actions, pass the message’s plain text to
CopyButtonso what’s copied matches what’s shown.
Accessibility
Labeling
- The component renders plain containers with no built-in author labeling. Convey who sent each message through visible cues — an author name, avatar, or the role styling — so the sender is clear without relying on color alone.
Known limitations
- No live-region announcements.
MessageBubbleadds noaria-live, so newly arriving messages aren’t automatically announced by screen readers. If you’re streaming assistant replies, manage an appropriate live region at the conversation level. roleis styling only. Theroleprop is a visual discriminator (user/assistant), not an ARIA role — it doesn’t change the element’s accessibility semantics.
Properties
MessageBubble.Root
Extends HTMLAttributes<HTMLDivElement>.
Prop | Required | Default | Type |
|---|---|---|---|
| role | false | 'user' | 'assistant' | |
| children | true | ReactNode |
MessageBubble.Content
Extends HTMLAttributes<HTMLDivElement>.
Prop | Required | Default | Type |
|---|---|---|---|
| children | true | ReactNode |
MessageBubble.Text
Extends Text props (Omit<TextProps, 'ref'>).
Prop | Required | Default | Type |
|---|---|---|---|
| children | true | ReactNode | |
| speed | false | number |
MessageBubble.Markdown
Extends MarkdownViewer props (Omit<MarkdownViewerProps, 'source'>).
Prop | Required | Default | Type |
|---|---|---|---|
| children | true | string |
MessageBubble.Footer
Extends HTMLAttributes<HTMLDivElement>.
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode |