Back to Copilotkit

Migrate Attachments

docs/snippets/shared/migration-guides/migrate-attachments.mdx

1.57.06.4 KB
Original Source

import { Steps, Step } from "fumadocs-ui/components/steps"; import { Callout } from "fumadocs-ui/components/callout";

Overview

CopilotKit now supports multimodal attachments — images, audio, video, and documents — through a unified attachments configuration. The new API replaces the image-only upload props with a single, extensible config object that supports custom upload handlers, file size limits, and any file type.

<Callout type="info"> For a full guide on the new attachments system, see [Multimodal Attachments](/multimodal-attachments). </Callout>

What's Changing

The following props and types are deprecated:

DeprecatedReplacement
imageUploadsEnabledattachments={{ enabled: true }}
inputFileAcceptattachments={{ accept: "..." }}
ImageUpload typeAttachment type
ImageUploadQueue componentAttachmentQueue component

These deprecated APIs will continue to work until the next major version but will log a warning in development mode. You can suppress warnings by calling suppressDeprecationWarnings() from @copilotkit/react-ui.

Minimum Version

  • New attachments API: available from v1.56.0
  • Deprecated APIs removed: next major version

Before / After

Basic image uploads

Before:

tsx
import { CopilotChat } from "@copilotkit/react-ui";

<CopilotChat imageUploadsEnabled={true} inputFileAccept="image/*" />;

After:

tsx
import { CopilotChat } from "@copilotkit/react-ui";

<CopilotChat
  attachments={{
    enabled: true,
    accept: "image/*",
  }}
/>;

Full multimodal support (images, audio, video, documents)

tsx
import { CopilotChat } from "@copilotkit/react-ui";

<CopilotChat
  attachments={{
    enabled: true,
    // accept defaults to "*/*" — all file types
  }}
/>;

Custom upload handler (e.g., upload to S3)

tsx
import { CopilotChat } from "@copilotkit/react-ui";

<CopilotChat
  attachments={{
    enabled: true,
    maxSize: 10 * 1024 * 1024, // 10MB
    onUpload: async (file) => {
      const url = await uploadToS3(file);
      return { type: "url", value: url, mimeType: file.type };
    },
  }}
/>;

Custom UI with AttachmentQueue

Before:

tsx
import { ImageUploadQueue } from "@copilotkit/react-ui";

<ImageUploadQueue images={selectedImages} onRemoveImage={handleRemove} />;

After:

tsx
import { AttachmentQueue } from "@copilotkit/react-ui";

<AttachmentQueue
  attachments={selectedAttachments}
  onRemoveAttachment={handleRemove}
/>;

Automated Migration (Codemod)

Run the codemod to automatically rename props, imports, and types:

bash
npx jscodeshift -t https://raw.githubusercontent.com/CopilotKit/CopilotKit/main/codemods/migrate-attachments.ts --parser=tsx --extensions=tsx,ts ./src

The codemod handles:

  • imageUploadsEnabled / inputFileAccept props → attachments={{ enabled: true, accept: "..." }}
  • import { ImageUploadQueue }import { AttachmentQueue }
  • import type { ImageUpload }import type { Attachment }

It does NOT transform:

  • Custom upload handler signatures (the onUpload return type changed — see Before / After)
  • ImageRenderer prop usage (the v2 attachment rendering is a different architecture)

After running, verify your app compiles and review the diff for anything the codemod couldn't handle.

Step-by-Step Migration (Manual)

<Steps> <Step> ### Replace props on CopilotChat
Replace `imageUploadsEnabled` and `inputFileAccept` with the `attachments` config object:

```tsx
// Remove these props:
// imageUploadsEnabled={true}
// inputFileAccept="image/*"

// Add this:
attachments={{ enabled: true, accept: "image/*" }}
```

If you want to support all file types (not just images), omit the `accept` field — it defaults to `"*/*"`.
</Step> <Step> ### Update component imports (if using custom UI)
If you imported `ImageUploadQueue` directly:

```tsx
// Before
import { ImageUploadQueue } from "@copilotkit/react-ui";
// After
import { AttachmentQueue } from "@copilotkit/react-ui";
```

Update the component props: `images` → `attachments`, `onRemoveImage` → `onRemoveAttachment`.
</Step> <Step> ### Update type imports (if referencing ImageUpload)
If you imported the `ImageUpload` type:

```tsx
// Before
import type { ImageUpload } from "@copilotkit/react-ui";
// After
import type { Attachment } from "@copilotkit/react-ui";
```

Note: the `Attachment` type has a different shape — see [Gotchas](#gotchas) below.
</Step> <Step> ### Suppress warnings (optional)
If you are aware of the deprecations but cannot migrate immediately:

```tsx
import { suppressDeprecationWarnings } from "@copilotkit/react-ui";

suppressDeprecationWarnings();
```
</Step> </Steps>

Gotchas

<Callout type="warning"> **Attachments are now actually sent to the LLM.** Previously, `imageUploadsEnabled` collected images in the UI but did not include them in messages sent to the model. The new `attachments` API sends all attachments as part of the message content. If you were using `imageUploadsEnabled` without expecting images to reach the model, be aware that they will now. </Callout> <Callout type="info"> **Default file type filter is broader.** The old `imageUploadsEnabled` defaulted to `image/*`. The new `attachments` API defaults to `*/*` (all file types). If you want to restrict to images only, set `accept: "image/*"` explicitly. </Callout>

Attachment type shape differs from ImageUpload:

tsx
// Old: ImageUpload
{ contentType: string; bytes: string }

// New: Attachment
{
  type: "image" | "audio" | "video" | "document";
  source: { type: "data"; value: string; mimeType: string }
        | { type: "url"; value: string; mimeType?: string };
  filename?: string;
  size?: number;
  status: "uploading" | "ready";
  metadata?: Record<string, unknown>;
}

Coexistence

The deprecated props and the new attachments prop can coexist in the same codebase during the transition period. If both imageUploadsEnabled and attachments are provided, attachments takes precedence.

The deprecated APIs will be removed in the next major version of CopilotKit.