Message プリミティブは個々のメッセージレンダリングを処理します。コンテンツ・パーツ、添付ファイル、ホバー状態を含むカスタム・メッセージのレンダリングを構築できます。
assistant-ui 入門 : プリミティブ – Message
作成 : Masashi Okumura (@classcat.com)
作成日時 : 03/29/2026
バージョン : assistant-ui@0.0.85
* 本記事は assistant-ui.com/docs の以下のページを参考にしています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
assistant-ui 入門 : プリミティブ – Message
コンテンツ・パーツ、添付ファイル、ホバー状態を含むカスタム・メッセージのレンダリングを構築できます。
Message プリミティブは個々のメッセージレンダリングを処理します: コンテンツ・パーツ、添付ファイル、引用、ホバー状態、エラー表示。それは各メッセージバブル内のビルディングブロックで、パーツパイプラインを通してテキスト、画像、ツール呼び出し等を解決します。
Preview

Code
import {
MessagePrimitive,
MessagePartPrimitive,
} from "@assistant-ui/react";
function UserMessage() {
return (
<MessagePrimitive.Root className="flex justify-end">
<div className="max-w-[80%] rounded-2xl bg-primary px-4 py-2.5 text-sm text-primary-foreground">
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "text") return <UserText />;
return null;
}}
</MessagePrimitive.Parts>
</div>
</MessagePrimitive.Root>
);
}
function AssistantMessage() {
return (
<MessagePrimitive.Root className="flex justify-start gap-3">
<div className="flex size-8 items-center justify-center rounded-full bg-primary/10 text-xs font-medium text-primary">
AI
</div>
<div className="max-w-[80%] rounded-2xl bg-muted px-4 py-2.5 text-sm">
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "text") return <AssistantText />;
return part.toolUI ?? null;
}}
</MessagePrimitive.Parts>
</div>
</MessagePrimitive.Root>
);
}
function UserText() {
return (
<p>
<MessagePartPrimitive.Text />
</p>
);
}
function AssistantText() {
return (
<p className="leading-relaxed">
<MessagePartPrimitive.Text />
</p>
);
}
クイックスタート
パーツのレンダリングを含む最小限のメッセージ :
import { MessagePrimitive } from "@assistant-ui/react";
<MessagePrimitive.Root>
<MessagePrimitive.Parts />
</MessagePrimitive.Root>
Root は、メッセージコンテキストを提供し、ホバー状態を追跡する <div> をレンダリングします。Parts はメッセージのコンテンツ・パーツを反復処理し、それぞれをレンダリングします。カスタム・コンポーネントがない場合、Parts は適切なデフォルトでレンダリングします: Text は、white-space: pre-line が適用された <p> としてレンダリングされ、ストリーミングインジケーターを表示し、Image は、MessagePartPrimitive.Image を通してレンダリングされ、ツール呼び出しは、ツール UI がグローバルまたはインラインで登録されていない限り、何もレンダリングしません。推論、ソース、ファイル、音声パーツはデフォルトで何もレンダリングしません。
ℹ️ ランタイム・セットアップ: プリミティブはランタイム・コンテキストを必要とします。UI をランタイム (例えば useLocalRuntime(…)) を持つ AssistantRuntimeProvider でラップします。See Pick a Runtime.
基本概念
Parts パイプライン
MessagePrimitive.Parts は children レンダリング関数を推奨するようになりました。それは現在の強化された part 状態を与えますので、インラインで分岐して必要な UI を正確に返すことができます。
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "text") return <MyTextRenderer />;
if (part.type === "image") return <MyImageRenderer />;
if (part.type === "tool-call")
return part.toolUI ?? <GenericToolUI {...part} />;
return null;
}}
</MessagePrimitive.Parts>
パーツ (部品)
Root
単一メッセージのためのコンテナ。asChild が設定されていない場合、<div> 要素をレンダリングします。
<MessagePrimitive.Root className="flex flex-col gap-2">
<MessagePrimitive.Quote>
{({ text }) => <blockquote className="mb-2 border-l pl-3 italic">{text}</blockquote>}
</MessagePrimitive.Quote>
<MessagePrimitive.Parts />
</MessagePrimitive.Root>
Parts
各コンテンツ part を、タイプごとに対応するコンポーネントを使用してレンダリングします。
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "text") return <MyTextRenderer />;
if (part.type === "image") return <MyImageRenderer />;
if (part.type === "tool-call")
return part.toolUI ?? <GenericToolUI {...part} />;
return null;
}}
</MessagePrimitive.Parts>
Attachments
すべてのユーザーメッセージの添付ファイルをレンダリングします。
<MessagePrimitive.Attachments>
{({ attachment }) => {
if (attachment.type === "image") {
const imageSrc = attachment.content?.find((part) => part.type === "image")?.image;
if (!imageSrc) return null;
return <img src={imageSrc} alt={attachment.name} className="max-w-xs rounded-lg" />;
}
if (attachment.type === "document") {
return (
<div className="rounded-lg border p-2 text-sm">
{attachment.name}
</div>
);
}
return null;
}}
</MessagePrimitive.Attachments>
Error
メッセージがエラーを含む場合のみ children をレンダリングします。
<MessagePrimitive.Error>
<ErrorPrimitive.Root className="mt-2 rounded-md border border-destructive/20 bg-destructive/5 p-3">
<ErrorPrimitive.Message />
</ErrorPrimitive.Root>
</MessagePrimitive.Error>
Quote
現在のメッセージが引用を含む場合、引用メタデータをレンダリングします。MessagePrimitive.Parts の上に配置します。
<MessagePrimitive.Quote>
{({ text, messageId }) => (
<blockquote className="mb-2 border-l pl-3 italic" data-message-id={messageId}>
{text}
</blockquote>
)}
</MessagePrimitive.Quote>
パターン
カスタム・テキスト・レンダリング
function MarkdownText() {
return (
<div className="prose prose-sm">
<MessagePartPrimitive.Text />
</div>
);
}
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "text") return <MarkdownText />;
return null;
}}
</MessagePrimitive.Parts>
エラー表示
<MessagePrimitive.Root>
<MessagePrimitive.Parts />
<MessagePrimitive.Error>
<div className="mt-2 rounded-md bg-destructive/10 p-2 text-sm text-destructive">
Something went wrong. Please try again.
</div>
</MessagePrimitive.Error>
</MessagePrimitive.Root>
以上