AI Elements
Message
One turn in a chat. The user's sits right in a bubble; the assistant's renders Markdown with Streamdown and can carry actions.
packages/design-system/components/ai-elements/message.tsx
Examples
How long does a brand sprint take?
A brand sprint runs two weeks: a kickoff, two rounds of concepts, and a handover with the files and a short guide.
Anatomy
- 01Message, the row
- 02Content, a bubble for the user
- 03Response, Markdown
- 04Actions, ghost icon buttons
Usage
import {
Message, MessageAction, MessageActions, MessageContent, MessageResponse,
} from "@repo/design-system/components/ai-elements/message";
<Message from={message.role}>
<MessageContent>
<MessageResponse>{part.text}</MessageResponse>
</MessageContent>
<MessageActions>
<MessageAction tooltip="Copy" onClick={copy}><CopyIcon /></MessageAction>
</MessageActions>
</Message>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| from* | "user" | "assistant" | "system" | none | User messages align right in a secondary bubble. |
| MessageResponse children | string | none | Markdown, rendered by Streamdown with code, math, mermaid and CJK plugins. Re-renders only when the text changes. |
| MessageAction tooltip / label | string | none | The tooltip, and the screen reader label (falls back to the tooltip). |
| MessageBranch defaultBranch / onBranchChange | number / (index) => void | none | For regenerated answers: page between versions with MessageBranchSelector. |
| className | string | none | Merged last with cn(). Use it for layout (width, margin), not to restyle the component. |
Guidance
Do
- Use MessageResponse for anything the model wrote.
Don't
- Render model output with dangerouslySetInnerHTML.