ComponentContext

ComponentContext holds the React Chat SDK UI override surface for a Channel subtree. Read it with useComponentContext(). Register overrides with WithComponents.

Best Practices

  • Scope overrides with WithComponents as close as possible to the subtree that needs them.
  • Prefer wrapping or lightly extending default SDK components before replacing whole surfaces.
  • Keep custom message UIs based on useMessageContext() and related hooks, not on assumed injected props.
  • Use local component props only when that component still exposes a supported prop surface.
  • Prefer wrapping the default ContextMenu or ContextMenuContent when you need custom menu behavior, so anchoring, submenu state, and dismissal stay aligned with the SDK.
  • Keep your override map documented, because most SDK UI customization now flows through ComponentContext.

Basic Usage

Read values from the context inside any Channel child:

import { useComponentContext } from "stream-chat-react";

export const CustomMessageListHeader = () => {
  const { EmptyStateIndicator, MessageActions } = useComponentContext();
  return (
    <div>
      <span>
        {EmptyStateIndicator ? "empty state available" : "no override"}
      </span>
      <span>
        {MessageActions ? "custom actions registered" : "default actions"}
      </span>
    </div>
  );
};

Registering Overrides With WithComponents

WithComponents merges the nearest override set into the existing ComponentContext. Inner wrappers win over outer wrappers.

import {
  Channel,
  ChannelHeader,
  MessageComposer,
  MessageList,
  Thread,
  Window,
  WithComponents,
} from "stream-chat-react";

export const App = () => {
  return (
    <WithComponents
      overrides={{
        MessageComposerUI: CustomMessageComposer,
        Message: CustomMessage,
        MessageActions: CustomMessageActions,
      }}
    >
      <Channel>
        <Window>
          <ChannelHeader />
          <MessageList />
          <MessageComposer />
        </Window>
        <Thread />
      </Channel>
    </WithComponents>
  );
};

You can scope overrides more narrowly too:

import {
  Channel,
  MessageComposer,
  MessageList,
  Thread,
  Window,
  WithComponents,
} from "stream-chat-react";

export const App = () => {
  return (
    <WithComponents overrides={{ MessageComposerUI: MainChannelInput }}>
      <Channel>
        <Window>
          <MessageList />
          <MessageComposer />
        </Window>
        <WithComponents overrides={{ MessageComposerUI: ThreadInputOverride }}>
          <Thread />
        </WithComponents>
      </Channel>
    </WithComponents>
  );
};

Message and VirtualMessage overrides should read SDK state from hooks like useMessageContext() instead of assuming the SDK injects message UI props directly.

Current Override Keys

The current ComponentContext value includes the following keys.

Composer And Input

Key Use for
AdditionalMessageComposerActions extra composer action buttons next to the textarea
AttachmentPreviewList the shared preview list in MessageComposer
AttachmentSelector the attachment selector UI
AttachmentSelectorInitiationButtonContents the selector button contents
AudioRecorder the voice-recording composer surface
AutocompleteSuggestionItem individual suggestion-list items
AutocompleteSuggestionList the suggestion-list container
CommandChip the selected command chip
CooldownTimer the slow-mode cooldown UI
EditedMessagePreview the edit-preview row shown by the composer
EmojiPicker the emoji picker trigger and picker UI
FileDragAndDropContent the drag-and-drop overlay content
FileSizeIndicator formatted file-size labels used by attachment previews
ImagePlaceholder the failed-image placeholder UI
MessageComposerUI the high-level message composer UI
LinkPreviewList link previews inside the composer preview stack
ProgressIndicator determinate upload progress UI used inside composer previews
RecordingPermissionDeniedNotification the recorder permission-denied UI
SendButton the send button
SendToChannelCheckbox the thread reply "also send to channel" checkbox
ShareLocationDialog the location-sharing dialog UI
StartRecordingAudioButton the audio-recording start button
StopAIGenerationButton the AI generation stop button in composer actions
TextareaComposer the text input control
UploadedSizeIndicator uploaded-vs-total size UI for file and audio uploads
VoiceRecordingPreviewSlot the dedicated voice-recording preview slot above attachments
emojiSearchIndex custom emoji search implementation for the composer

Message, Notifications, And Lists

Key Use for
Attachment message attachment rendering
AttachmentFileIcon the file-type icon shown on file attachments
DateSeparator date separators in message lists
EmptyStateIndicator empty list or empty thread placeholders
GiphyPreviewMessage giphy preview rows in message lists
HeaderComponent content rendered above MessageList
LoadingErrorIndicator loading error UI
LoadingIndicator loading UI while querying or paginating
MessageActions the message actions surface
MessageAlsoSentInChannelIndicator the thread "also sent in channel" indicator
MessageBlocked moderation-blocked message UI
MessageBouncePrompt bounced message prompt content
MessageDeleted alternate deleted-message renderer with no default
MessageDeletedBubble deleted message bubble renderer
MessageEditedIndicator Custom UI component to display the "Edited" label and tooltip when a message has been edited
MessageListItem wrapper for each list item
MessageListMainPanel the main panel around the message list
MessageListWrapper wrapper around the list contents
MessageRepliesCountButton replies-count button
MessageReactions the inline reactions list
MessageReactionsDetail reaction detail dialog content
MessageStatus message delivery and read status
MessageSystem system message rendering
MessageTimestamp per-message timestamp UI
MessageTranslationIndicator translation indicator UI
MessageUI the default non-virtualized message renderer (replaces the deprecated Message key)
NewMessageNotification the "new messages" notification
Notification a single rendered notification item in NotificationList
NotificationAnnouncer screen-reader announcements for notifications
NotificationList the client-notification list UI
PinIndicator pinned-message indicator
QuotedMessage quoted message rendering in message bubbles
ReminderNotification reminder UI in messages
ScrollToLatestMessageButton the scroll-to-latest-message button in a message list
StreamedMessageText streamed AI text rendering
TypingIndicator the message-list typing indicator
UnreadMessagesNotification the unread notification while scrolled away
UnreadMessagesSeparator the unread separator row
VirtualMessage the virtualized message renderer

Reactions, Polls, And Media

Key Use for
Avatar single-user avatar rendering
AvatarStack stacked avatar rendering
BaseImage low-level image rendering and fallbacks
Gallery gallery carousel UI
GalleryUI the gallery viewer UI rendered by Gallery
Modal the modal shell used by SDK features
ModalGallery gallery viewer content
PollActions poll actions renderer
PollContent poll body renderer
PollCreationDialog poll creation dialog contents
PollHeader poll header renderer
PollOptionSelector poll option selector UI
QuotedMessagePreview quoted-message preview inside the composer
ReactionSelector the reaction selector UI
ReactionSelectorExtendedList the expanded reaction picker used inside MessageReactionsDetail
AttachmentUploadProgressIndicator upload progress shown on a message attachment that is still uploading
VideoPlayer video playback UI
reactionOptions shared reaction options for selector and list components

Channel Preview, Thread, Search, And Shared Utility UI

Key Use for
CalloutDialog callout-dialog contents
ChannelListHeader the header of the channel-list sidebar
ChannelListUI the default channel-list container and loading/error UI
ChannelListItemUI the default channel-list row UI
ChannelListItemActionButtons action buttons inside ChannelListItemUI
ContextMenu the high-level anchored context-menu surface
ContextMenuContent menu body, submenu stack, and back-navigation content
HeaderEndContent content rendered at the end of sidebar headers (ChannelListHeader, ThreadListHeader); no default, slot is empty if omitted
HeaderStartContent content rendered at the start of content headers (ChannelHeader, ThreadHeader); no default, slot is empty if omitted
Search the main search UI
SearchBar the search input area
SearchResults the results pane
SearchResultsHeader results header content
SearchResultsPresearch the pre-query state for results
SearchSourceResultList the result-list UI for one source
SearchSourceResultListFooter end-of-list footer for one source
SearchSourceResults one source section in search results
SearchSourceResultsEmpty empty state for one source
SearchSourceResultsHeader header for one source section
SearchSourceResultsLoadingIndicator loading state for one source section
ThreadHead thread parent/header message at the top of thread lists
ThreadHeader thread header UI
ThreadListEmptyPlaceholder empty state in thread lists
ThreadListItem thread list item wrapper
ThreadListItemUI thread list item UI
ThreadListLoadingIndicator thread list loading UI
ThreadListUnseenThreadsBanner unseen-thread banner
ThreadStart thread-start marker or content
Timestamp shared timestamp component used by other UI

Choosing Between Props And Context

Use the local component prop when that component still exposes a supported prop surface. Use WithComponents and ComponentContext when you want to replace SDK-owned UI deeper in the tree.

Examples:

  • wrap a single MessageComposer or Thread subtree in WithComponents when only that composer should use a different MessageComposerUI
  • use <WithComponents overrides={{ MessageComposerUI: CustomInput }}> when you want every nested SDK input to use the same override
  • use <WithComponents overrides={{ MessageActions: CustomMessageActions }}> when you want to replace the default message action UI
  • use <WithComponents overrides={{ ContextMenu: CustomContextMenu }}> when you need to change anchored menu behavior such as outside-click dismissal or close animations without rebuilding the whole surface
Add Chat to my app: getstream.io/SKILL.md

The fastest way to build with Stream. Start a new project or improve an existing one. Full CLI and documentation integration out of the box.


Ask your agent:

/stream Build me a Social App with Feeds and Moderation.
/stream Any livestream calls running?
/stream Chat React v14: <Your Question>