Assistant Message
The reply is flush and renders markdown.
<Message from="assistant">
<Message.Content>{"Two files use a raw `button`."}</Message.Content>
</Message>Displays user or assistant conversation turns, including sending, streaming and failure states.
<Message from="user">
<Message.Content>Which files break the workspace rules?</Message.Content>
</Message>pnpm add @usefragments/uiThe npm package stays managed by your package manager. Import styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.
Import Message once, then compose its parts with dot notation.
Message.ContentMessage.ActionsMessage.TimestampMessage.AvatarMessage.ErrorThe user's words in a band bubble at the end, capped at 80% of the measure.
<Message from="user">
<Message.Content>Which files break the workspace rules?</Message.Content>
</Message>The reply is flush and renders markdown.
<Message from="assistant">
<Message.Content>{"Two files use a raw `button`."}</Message.Content>
</Message>A still caret at the end while the reply arrives.
const partial = "Two files need updated imports…";
<Message from="assistant" status="streaming">
<Message.Content>{partial}</Message.Content>
</Message>The meta line says Sending… until the message lands.
<Message from="user" status="pending">
<Message.Content>Summarise the changes on main.</Message.Content>
</Message>The failure block says what happened and offers Try again.
const partial = "The reply was interrupted.";
const retry = () => {};
<Message from="assistant" status="error" onRetry={retry}>
<Message.Content>{partial}</Message.Content>
</Message>A relative time in the meta line.
const sentAt = new Date(2026, 9, 4, 10, 30);
<Message from="user" timestamp={sentAt}>
<Message.Content>Thanks!</Message.Content>
</Message>Copy and regenerate beside the meta line.
import { Copy } from "@phosphor-icons/react";
const reply = "Two files need updated imports.";
<Message
from="assistant"Opt in when more than two people talk.
<Message from="user" avatar={<Message.Avatar>AL</Message.Avatar>}>
<Message.Content>Can you check main?</Message.Content>
</Message>Prop | Type | Default | Description |
|---|---|---|---|
actions | React.ReactNode | Not set | Actions for the message (copy, regenerate), shown on hover or focus where a pointer hovers, always on touch |
Actions.childrenRequired | React.ReactNode | Not set | — |
avatar | React.ReactNode | Not set | Opt-in avatar slot, usually Message.Avatar. No avatar is drawn by default |
Avatar.alt | string | undefined | Not set | Alt text for the image. |
Avatar.children | React.ReactNode | Not set | Initials or a glyph when there is no image. |
Avatar.src | string | undefined | Not set | Image URL. |
childrenRequired | React.ReactNode | Not set | Message parts, usually Message.Content |
Content.childrenRequired | React.ReactNode | Not set | A string from the assistant renders as markdown; from the user it keeps its line breaks. |
Error.actions | React.ReactNode | Not set | More actions beside retry (for example "Ask differently"). |
Error.children | React.ReactNode | Not set | What went wrong. |
Error.onRetry | (() => void) | undefined | Not set | Retry handler; adds the "Try again" action. Defaults to the message's `onRetry`. |
Error.retryLabel | string | undefined | Not set | Label of the retry action. |
fromRequired | MessageFromuserassistant | Not set | Who wrote the message: the user's bubble sits at the end, the assistant's reply is flush |
onRetry | (() => void) | undefined | Not set | Retry a failed message; the failure block offers Try again |
status | MessageStatus | undefinedpendingerrorstreamingcomplete | complete | Where the message stands: pending shows Sending…, streaming a still caret at the end, error a failure block |
timestamp | Date | undefined | Not set | When the message was sent; shown in the meta line |
Timestamp.date | Date | undefined | Not set | Date to show. Defaults to the message's `timestamp`. |
Timestamp.format | ((date: Date) => string) | undefined | Not set | Custom format function. |