Documents
attachment
attachment
Type
External
Status
Published
Created
Mar 17, 2026
Updated
Mar 17, 2026

import { AttachmentSample } from "@/components/docs/samples/attachment";

**Note:** These components provide the UI for attachments, but you also need to configure attachment adapters in your runtime to handle file uploads and processing. See the [Attachments Guide](/docs/guides/attachments) for complete setup instructions.

Getting Started#

Add attachment#

<InstallCommand shadcn={["attachment"]} />

This adds a /components/assistant-ui/attachment.tsx file to your project, which you can adjust as needed.

Use in your application#

import {
  ComposerAttachments,
  ComposerAddAttachment,
} from "@/components/assistant-ui/attachment";

const Composer: FC = () => {
  return (
    <ComposerPrimitive.Root className="...">
      <ComposerAttachments />
      <ComposerAddAttachment />

      <ComposerPrimitive.Input
        autoFocus
        placeholder="Write a message..."
        rows={1}
        className="..."
      />
      <ComposerAction />
    </ComposerPrimitive.Root>
  );
};
import { UserMessageAttachments } from "@/components/assistant-ui/attachment";

const UserMessage: FC = () => {
  return (
    <MessagePrimitive.Root className="...">
      <UserActionBar />

      <UserMessageAttachments />

      <div className="...">
        <MessagePrimitive.Parts />
      </div>

      <BranchPicker className="..." />
    </MessagePrimitive.Root>
  );
};

API Reference#

Composer Attachments#

ComposerPrimitive.Attachments#

Renders all attachments in the composer.

<ParametersTable
type="ComposerPrimitiveAttachmentsProps"
parameters={[
{
name: "components",
type: "AttachmentComponents",
description: "Components to render for different attachment types.",
children: [
{
type: "AttachmentComponents",
parameters: [
{
name: "Image",
type: "ComponentType",
description: "Component for image attachments.",
},
{
name: "Document",
type: "ComponentType",
description: "Component for document attachments (PDF, etc.).",
},
{
name: "File",
type: "ComponentType",
description: "Component for generic file attachments.",
},
{
name: "Attachment",
type: "ComponentType",
description: "Fallback component for all attachment types.",
},
],
},
],
},
]}
/>

ComposerPrimitive.AddAttachment#

A button that opens the file picker to add attachments.

<ParametersTable
type="ComposerPrimitiveAddAttachmentProps"
parameters={[
{
name: "multiple",
type: "boolean",
default: "true",
description: "Allow selecting multiple files at once.",
},
{
name: "asChild",
type: "boolean",
default: "false",
description: "Merge props with child element instead of rendering a wrapper button.",
},
]}
/>

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

Message Attachments#

MessagePrimitive.Attachments#

Renders all attachments in a user message.

<ParametersTable
type="MessagePrimitiveAttachmentsProps"
parameters={[
{
name: "components",
type: "AttachmentComponents",
description: "Components to render for different attachment types (same as ComposerPrimitive.Attachments).",
},
]}
/>

Attachment Primitives#

AttachmentPrimitive.Root#

Container for a single attachment.

<ParametersTable
type="AttachmentPrimitiveRootProps"
parameters={[
{
name: "asChild",
type: "boolean",
default: "false",
description: "Merge props with child element instead of rendering a wrapper div.",
},
]}
/>

AttachmentPrimitive.Name#

Renders the attachment's file name.

AttachmentPrimitive.Remove#

A button to remove the attachment from the composer.

<ParametersTable
type="AttachmentPrimitiveRemoveProps"
parameters={[
{
name: "asChild",
type: "boolean",
default: "false",
description: "Merge props with child element instead of rendering a wrapper button.",
},
]}
/>

Attachment Types#

Attachments have the following structure:

type Attachment = {
  id: string;
  type: "image" | "document" | "file" | (string & {});
  name: string;
  contentType?: string;
  file?: File;
  status:
    | { type: "running" | "requires-action" | "incomplete"; progress?: number }
    | { type: "complete" };
};

The type field accepts custom strings (e.g. "data-workflow") beyond the built-in types. When an unknown type is encountered, the generic Attachment component is used as a fallback. The contentType field is optional — it can be omitted for non-file attachments where a MIME type is not meaningful.

  • Thread - Main chat interface that displays attachments
  • Attachments Guide - Complete setup instructions for attachment adapters