Docs

React UI

Message rendering

Render default message parts first, then customize Markdown, attachments, tool cards, and actions.

This recipe keeps default rendering for most parts and customizes only the parts that usually need product UI: Markdown text, attachments, and tool cards.

If you only need user/assistant alignment and ordinary text rendering, stay with <Thread.Messages /> and style the emitted data-role attributes first.

Full renderer

import { Message } from "@anvia/react-ui";

export function AgentMessage() {
  return (
    <Message.Root className="message">
      <Message.Content className="message-content">
        <Message.Parts>
          {(part) => {
            if (part.type === "text") {
              return (
                <Message.Part className="text-part">
                  <Message.Markdown
                    components={{
                      code(props) {
                        return <Message.CodeBlock {...props} />;
                      },
                    }}
                  />
                </Message.Part>
              );
            }

            if (part.type === "attachment") {
              return (
                <Message.Part className="attachment-part">
                  <Message.Attachment className="attachment-card" />
                </Message.Part>
              );
            }

            if (part.type === "tool") {
              return (
                <Message.Part className="tool-part">
                  <Message.Tool className="tool-card" renderWhen="always" />
                </Message.Part>
              );
            }

            return <Message.Part className="message-part" />;
          }}
        </Message.Parts>
      </Message.Content>

      <Message.Actions className="message-actions">
        <Message.Copy>Copy</Message.Copy>
        <Message.Regenerate>Retry</Message.Regenerate>
      </Message.Actions>
    </Message.Root>
  );
}

Role-aware layout

Message.Root emits data-role, so the same component can style user and assistant messages differently. Keep the user bubble small and let assistant content use the main reading width.

Copy and regenerate controls

Actions can use regular buttons or design-system components with asChild.

<Message.Actions className="message-actions">
  <Message.Copy asChild>
    <button type="button">Copy answer</button>
  </Message.Copy>
  <Message.Regenerate asChild>
    <button type="button">Regenerate</button>
  </Message.Regenerate>
</Message.Actions>

When to branch

Branch inside Message.Parts only for part types that need a different experience. For ordinary data, reasoning, and error parts, keep <Message.Part /> as the fallback so the default renderer continues to work.