Radix UI Primitives

MessagePrimitive

Components for rendering message content, parts, and attachments.

A single message in a conversation. Messages may consist of multiple parts.

Anatomy

import { MessagePrimitive } from "@assistant-ui/react";

const UserMessage = () => (
  <MessagePrimitive.Root>
    User: <MessagePrimitive.Parts />
    <BranchPicker />
    <ActionBar />
  </MessagePrimitive.Root>
);

const AssistantMessage = () => (
  <MessagePrimitive.Root>
    Assistant: <MessagePrimitive.Parts />
    <BranchPicker />
    <ActionBar />
  </MessagePrimitive.Root>
);

API Reference

Root

Containts all parts of the message.

This primitive renders a <div> element unless asChild is set.

MessagePrimitiveRootProps
asChild: boolean= false

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

Parts

The content of the message. This renders a separate component for each content part of the message.

MessagePrimitiveContentProps
components?: ContentPartComponents

The components to render for each content part.

ContentPartComponents
Text?: TextContentPartComponent

The component to render for each text content part.

Image?: ImageContentPartComponent

The component to render for each image content part.

Source?: SourceContentPartComponent

The component to render for each source content part.

File?: FileContentPartComponent

The component to render for each file content part.

Unstable_Audio?: Unstable_AudioContentPartComponent

The component to render for each audio content part.

tools?: object

The component to render for each tool call content part.

by_name?: Record<string, ToolCallContentPartComponent>

The components to render for each tool call content part.

Fallback?: ToolCallContentPartComponent

The fallback component to render for tool call content parts.

ToolGroup?: ComponentType<PropsWithChildren<{ startIndex: number; endIndex: number }>>

Component for rendering grouped consecutive tool calls. When provided, consecutive tool-call content parts will be automatically grouped and wrapped with this component.

ToolGroupProps
startIndexrequired: number

Index of the first tool call in the group.

endIndexrequired: number

Index of the last tool call in the group.

childrenrequired: ReactNode

The rendered tool call components within the group.

PartByIndex

Renders a single message part at the specified index.

<MessagePrimitive.PartByIndex
  index={0}
  components={{
    Text: MyTextComponent,
    Image: MyImageComponent
  }}
/>
MessagePrimitive.PartByIndex.Props
indexrequired: number

The index of the message part to render.

components?: ContentPartComponents

The components to render for the message part.

Attachments

Renders all attachments of the message.

MessagePrimitive.Attachments.Props
components?: AttachmentComponents

The components to render for each attachment.

AttachmentComponents
Image?: ComponentType

The component to render for image attachments.

Document?: ComponentType

The component to render for document attachments.

File?: ComponentType

The component to render for file attachments.

Attachment?: ComponentType

The fallback component to render for any attachment type.

AttachmentByIndex

Renders a single attachment at the specified index within the message.

<MessagePrimitive.AttachmentByIndex
  index={0}
  components={{
    Image: MyImageAttachment,
    Document: MyDocumentAttachment
  }}
/>
MessagePrimitive.AttachmentByIndex.Props
indexrequired: number

The index of the attachment to render.

components?: AttachmentComponents

The components to render for the attachment.

useMessageQuote()

A hook that returns the quote info attached to the current message, if any. Reads from message.metadata.custom.quote.

import { useMessageQuote } from "@assistant-ui/react";

const QuoteBlock = () => {
  const quote = useMessageQuote();
  if (!quote) return null;

  return (
    <div className="mb-2 flex items-start gap-1.5 text-sm italic text-muted-foreground">
      {quote.text}
    </div>
  );
};

Returns: QuoteInfo | undefined

type QuoteInfo = {
  readonly text: string;       // the quoted plain text
  readonly messageId: string;  // the source message ID
};

See the Quoting guide for a complete walkthrough.

Error

Renders children only if the message has an error status.

<MessagePrimitive.Error>
  {/* rendered if the message has an error status */}
  <ErrorPrimitive.Root>
    <ErrorPrimitive.Message />
  </ErrorPrimitive.Root>
</MessagePrimitive.Error>