Attachment Previews in Message Composer

This section shows how to customize attachment previews in MessageComposer. The default composer uses a preview stack made of VoiceRecordingPreviewSlot, AttachmentPreviewList, and LinkPreviewList.

Best Practices

  • Override only the preview components you actually need.
  • Keep attachment previews compact so they do not crowd the composer.
  • Handle custom attachment objects through UnsupportedAttachmentPreview.
  • Customize voice recordings through VoiceRecordingPreviewSlot, not AttachmentPreviewList.
  • Keep link previews separate from attachment previews; they are rendered by LinkPreviewList.
  • Prefer overriding low-level upload indicators through WithComponents before replacing whole preview components.

Default Attachment Preview Types

AttachmentPreviewList renders previews for:

  • audio
  • file
  • image
  • video
  • geolocation previews from message.shared_location
  • unsupported local attachments via UnsupportedAttachmentPreview

Voice recordings are rendered in the separate VoiceRecordingPreviewSlot above the main attachment preview list.

Customize Default Attachment Previews

Wrap AttachmentPreviewList with the preview components you want to replace, then register it with WithComponents:

import {
  AttachmentPreviewList,
  Channel,
  MessageComposer,
  WithComponents,
} from "stream-chat-react";

import { VideoAttachmentPreview } from "./AttachmentPreviews";

const CustomAttachmentPreviewList = () => (
  <AttachmentPreviewList VideoAttachmentPreview={VideoAttachmentPreview} />
);

const App = () => (
  <WithComponents
    overrides={{ AttachmentPreviewList: CustomAttachmentPreviewList }}
  >
    <Channel>
      <MessageComposer />
    </Channel>
  </WithComponents>
);

The replaceable preview components are:

  • AudioAttachmentPreview
  • FileAttachmentPreview
  • GeolocationPreview
  • ImageAttachmentPreview
  • UnsupportedAttachmentPreview
  • VideoAttachmentPreview

Upload Progress And Size UI

The default preview surfaces already split upload UI by attachment type:

  • file previews use a progress ring plus uploaded-vs-total size
  • audio previews use the same upload primitives until playback metadata is available
  • image and video previews use the progress ring as an overlay

The low-level pieces are configurable through ComponentContext:

  • ProgressIndicator
  • UploadedSizeIndicator
  • FileSizeIndicator

Use those when you want to change the upload progress UI without replacing FileAttachmentPreview, AudioAttachmentPreview, or MediaAttachmentPreview.

Customize Custom Attachment Previews

Custom attachment objects added through the composer are rendered by UnsupportedAttachmentPreview. Use it to branch on your own attachment types:

import type { UnsupportedAttachmentPreviewProps } from "stream-chat-react";
import { AttachmentPreviewList } from "stream-chat-react";

import { EventPreview } from "./EventAttachmentPreview";

const CustomUnsupportedAttachmentPreview = (
  props: UnsupportedAttachmentPreviewProps,
) => {
  const { attachment } = props;

  if (attachment.type === "event") {
    return <EventPreview {...props} />;
  }

  return null;
};

const CustomAttachmentPreviewList = () => (
  <AttachmentPreviewList
    UnsupportedAttachmentPreview={CustomUnsupportedAttachmentPreview}
  />
);

Customize Voice Recording Previews

Voice recordings are not part of AttachmentPreviewList. Override VoiceRecordingPreviewSlot instead:

import {
  Channel,
  MessageComposer,
  VoiceRecordingPreviewSlot,
  WithComponents,
} from "stream-chat-react";

import { CustomVoiceRecordingPreview } from "./CustomVoiceRecordingPreview";

const CustomVoiceRecordingPreviewSlot = () => (
  <VoiceRecordingPreviewSlot
    VoiceRecordingPreview={CustomVoiceRecordingPreview}
  />
);

const App = () => (
  <WithComponents
    overrides={{
      AttachmentPreviewList: CustomAttachmentPreviewList,
      VoiceRecordingPreviewSlot: CustomVoiceRecordingPreviewSlot,
    }}
  >
    <Channel>
      <MessageComposer />
    </Channel>
  </WithComponents>
);