This is beta documentation for Stream Chat React SDK v14. For the latest stable version, see the latest version (v13) .

Channel Preview

The ChannelList Preview prop lets you replace the UI for each channel row. If you do not provide a custom preview, the SDK uses ChannelPreviewMessenger.

Best Practices

  • Preserve the selection handler so active channel switching keeps working.
  • Keep preview rendering lightweight because it runs for every item in the list.
  • Prefer the provided displayTitle, displayImage, and groupChannelDisplayInfo values over recomputing channel metadata yourself.
  • Use latestMessagePreview for the preview text instead of rebuilding message summaries from scratch.
  • If you build summaries from useLatestMessagePreview(), handle native giphy messages separately from ordinary images.
  • Keep custom CSS aligned with the current preview structure and button semantics.

Basic Usage

To customize the row UI, pass your component to ChannelList:

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

const CustomChannelPreview = ({ latestMessagePreview }) => (
  <span>{latestMessagePreview}</span>
);

<ChannelList Preview={CustomChannelPreview} />;

Default Preview Behavior

ChannelPreviewMessenger:

  • renders ChannelAvatar by default, not the plain Avatar component
  • uses displayTitle, displayImage, and groupChannelDisplayInfo from useChannelPreviewInfo()
  • renders SummarizedMessagePreview for the last-message summary
  • uses ChannelPreviewTimestamp for the timestamp
  • marks the selected row with aria-pressed
  • renders ChannelPreviewActionButtons, which use a context menu plus archive or mute actions depending on channel type

Props

PropDescriptionType
activeWhether the row channel is currently selected.boolean
activeChannelThe active channel from chat context.Channel
AvatarCustom avatar component. It receives the same props as ChannelAvatar. Defaults to ChannelAvatar.component
channelThe channel instance for the row.Channel
channelUpdateCountCounter value used to force a rerender when the parent list wants to refresh previews.number
classNameCustom class name merged onto the preview button.string
displayImageResolved image to display for the row. For direct messages, this can include the SDK's fallback to the other member's image.string
displayTitleResolved display title for the row. For direct messages and group channels, this can be synthesized from members.string
getLatestMessagePreviewCustom function to build the preview text.(channel: Channel, t: TranslationContextValue["t"], userLanguage: TranslationContextValue["userLanguage"], isMessageAIGenerated: ChatContextValue["isMessageAIGenerated"]) => ReactNode
groupChannelDisplayInfoResolved group-avatar data for channels with multiple visible members.GroupChannelDisplayInfo
lastMessageThe latest message currently used to build the row summary.LocalMessage
latestMessageDeprecated alias for latestMessagePreview.ReactNode
latestMessagePreviewRendered preview of the latest message.ReactNode
messageDeliveryStatusDelivery status for your own latest message. Use it when you replace the summary UI.MessageDeliveryStatus
mutedWhether the current user has muted the channel.boolean
onSelectCustom click handler for the row.(event: React.MouseEvent) => void
PreviewCustom preview component used by ChannelPreview. Defaults to ChannelPreviewMessenger.component
setActiveChannelSetter used by the default row click handler.ChatContextValue["setActiveChannel"]
unreadUnread message count for the channel.number
watchersWatcher query options forwarded when activating the channel.{ limit?: number; offset?: number }

Delivery Status And Summaries

If you build your own row, prefer reusing the SDK helpers that match the default preview:

  • ChannelPreviewTimestamp
  • SummarizedMessagePreview
  • getChannelDisplayImage(channel)
  • useChannelDisplayName(channel)

That keeps custom previews aligned with the current channel title, avatar, timestamp, and delivery-status behavior without depending on removed standalone status-icon exports.

If you go lower-level and switch on useLatestMessagePreview().type, include a giphy case. Native giphy messages now resolve to their own preview type instead of being folded into image.