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

MessageList

MessageList renders the standard scrollable list of channel messages. It consumes Channel state and actions, injects date separators when enabled, and renders unread and notification UI around the list.

By default, MessageList reads its messages from ChannelStateContext:

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

const Component = () => {
  const { messages } = useChannelStateContext();

  return <div>{messages.length}</div>;
};

Best Practices

  • Render MessageList under Channel.
  • Avoid passing messages unless you need to control the list contents directly.
  • Use renderMessages only for structural list changes and keep it stable with useCallback or module scope.
  • Customize message actions through the MessageActions component, not through a dedicated list prop.
  • Preserve list semantics such as <li> wrappers when replacing the default renderer.

Basic Usage

import {
  Channel,
  ChannelHeader,
  MessageInput,
  MessageList,
  Window,
} from "stream-chat-react";

const App = () => (
  <Channel>
    <Window>
      <ChannelHeader />
      <MessageList />
      <MessageInput />
    </Window>
  </Channel>
);

If you need to render a custom message array:

const customMessages = [
  // ...
];

<MessageList messages={customMessages} />;

Message Grouping

MessageList groups consecutive messages by user and time. The default renderer applies grouping classes such as str-chat__li--top, str-chat__li--middle, str-chat__li--bottom, and str-chat__li--single.

You can customize grouping with the groupStyles callback or disable grouping with noGroupByUser.

Custom Message List Rendering

Use renderMessages to replace the final rendering pipeline while still reusing the SDK processing step:

import {
  MessageList,
  defaultRenderMessages,
  type MessageRenderer,
} from "stream-chat-react";

const customRenderMessages: MessageRenderer = (options) => {
  const elements = defaultRenderMessages(options);

  elements.push(<li key="caught-up">You're all caught up!</li>);

  return elements;
};

const CustomMessageList = () => (
  <MessageList renderMessages={customRenderMessages} />
);

Returned elements should have stable key values. Wrapping rendered items in <li> elements keeps the markup compatible with the default list layout.

Notifications And Unread UI

The default MessageList renders these pieces around the message list:

  • UnreadMessagesNotification
  • NewMessageNotification
  • ScrollToLatestMessageButton
  • MessageListNotifications

MessageListNotifications is the notifications container. NewMessageNotification and ScrollToLatestMessageButton are separate components and are not configured through MessageListNotifications.

Props

MessageList forwards the current message UI props to the Message component it renders, including:

  • additionalMessageInputProps
  • closeReactionSelectorOnClick
  • disableQuotedMessages
  • formatDate
  • getDeleteMessageErrorNotification
  • getFlagMessageErrorNotification
  • getFlagMessageSuccessNotification
  • getMarkMessageUnreadErrorNotification
  • getMarkMessageUnreadSuccessNotification
  • getMuteUserErrorNotification
  • getMuteUserSuccessNotification
  • getPinMessageErrorNotification
  • Message
  • messageActions
  • onlySenderCanEdit
  • onMentionsClick
  • onMentionsHover
  • onUserClick
  • onUserHover
  • openThread
  • pinPermissions
  • reactionDetailsSort
  • renderText
  • retrySendMessage
  • showAvatar
  • sortReactions
  • sortReactionDetails
  • unsafeHTML

For custom message actions, provide a custom MessageActions component through WithComponents or pass a custom messageActions array to the list.

PropDescriptionType
disableDateSeparatorDisables injected date separators.boolean
groupStylesCustom callback for message grouping.MessageListProps["groupStyles"]
hasMoreWhether older messages can be loaded.boolean
headElement rendered above the thread reply list. Used internally by Thread.ReactElement
headerPositionPosition where HeaderComponent should render.number
hideDeletedMessagesHides deleted-message bubbles.boolean
hideNewMessageSeparatorHides the separator inserted for unread incoming messages in watched but inactive channels.boolean
internalInfiniteScrollPropsAdditional props for the internal infinite scroll component.Partial<InfiniteScrollProps>
jumpToLatestMessageLoads the latest message set after the list has jumped away from it.() => Promise<void>
loadingMoreWhether older messages are currently loading.boolean
loadingMoreNewerWhether newer messages are currently loading.boolean
loadMoreLoads older messages.() => Promise<void>
loadMoreNewerLoads newer messages.() => Promise<void>
maxTimeBetweenGroupedMessagesMaximum time window for grouping messages together.number
messageLimitPage size used when paginating messages.number
messagesCustom message array overriding ChannelStateContext.messages.LocalMessage[]
noGroupByUserDisables user-based grouping.boolean
renderMessagesCustom render pipeline for the processed list.MessageRenderer
returnAllReadDataKeeps read receipts for every own message.boolean
reviewProcessedMessageLets you inspect and adjust processed list items such as date separators.ProcessMessagesParams["reviewProcessedMessage"]
scrolledUpThresholdThreshold under which the list is considered close enough to the bottom to auto-scroll.number
showUnreadNotificationAlwaysShows the unread notification even when the unread separator is not in view.boolean
threadListMarks the list as a thread list.boolean