Info:
This is release candidate documentation for Stream Chat React Native SDK v10. For the latest stable version, see the latest version (v9).

Message UI components

The default MessageItemView is built from parts, and stream-chat-react-native exports them for a message view of your own. Each part reads the message from MessageContext, so most need no props inside a message. Each is an override key of the same name, except MessageTextContainer, whose text the MessageText key replaces.

Best practices

  • Compose these parts instead of rebuilding them. They handle states that are easy to miss, such as a message that is still sending, a failed message, an edited one or a reply sent to the channel.
  • Replace one part through its override key, and keep the rest of the default view.
  • Wrap the exported part when you only add to it, as the sample below does, so its own behavior stays.
  • Change the actions in the message menu through messageActions on Channel, not through these parts. See Message actions.

Basic usage

This replacement keeps the default status icon and adds "Read" once another member has read the message:

src/MessageStatusWithText.tsx
import { StyleSheet, Text } from "react-native";
import {
  MessageStatus,
  type MessageStatusProps,
  useIsMessageReadByOthers,
  useMessageContext,
  WithComponents,
} from "stream-chat-react-native";

const MessageStatusWithText = (props: MessageStatusProps) => {
  const { message } = useMessageContext();
  const read = useIsMessageReadByOthers({ message });

  return (
    <>
      <MessageStatus {...props} />
      {read ? <Text style={styles.read}>Read</Text> : null}
    </>
  );
};

const overrides = { MessageStatus: MessageStatusWithText };

export const MessagesWithReadText = ({
  children,
}: {
  children: React.ReactNode;
}) => <WithComponents overrides={overrides}>{children}</WithComponents>;

const styles = StyleSheet.create({
  read: { fontSize: 12 },
});

Status indicators builds more of them.

Available components

Component Renders Exported
MessageAuthor the sender's avatar, or a spacer of the same width yes
MessageHeader the reminder, pinned and sent-to-channel marks above the bubble yes
MessagePinnedHeader "Pinned by" and the name, or "You" yes
MessageReminderHeader "Reminder set" or "Reminder overdue", with the time left yes
MessageSavedForLaterHeader "Saved For Later" yes
SentToChannelHeader "Also sent in channel" or "Replied to a thread", with View yes
MessageTextContainer the message's text, as Markdown yes, not an override key
MessageFooter the sender's name, the status, the time and "Edited" yes
MessageTimestamp the time yes
MessageStatus the delivery status icon of the user's own messages yes
MessageReplies the replies button, with the participants' avatars yes
MessageRepliesAvatars the avatars of up to three thread participants yes
MessageDeleted "Message deleted" and the footer yes
MessageError the error badge on a failed or error message yes
MessageBlocked a message blocked by moderation, in place of the message view yes
MessageBounce the dialog of a bounced message yes
MessageSystem a system message, in place of Message yes
StreamingMessageView the text of an AI-generated message, revealed as it streams yes

MessageAuthor

Renders the sender's avatar on messages aligned left. Where the avatar doesn't show, it renders an empty view of the same size, so the bubbles of a group stay aligned. It re-renders only when lastGroupMessage or the sender's ID, name or image changes.

Prop Type Default Description
lastGroupMessage boolean from MessageContext Shows the avatar when showAvatar isn't set.
message LocalMessage from MessageContext The message whose sender is shown.
showAvatar boolean from MessageContext Shows or hides the avatar, whatever the group.
size "sm" | "md" | "lg" | "xl" | "xs" | "2xl" 'md' The avatar's size.

MessageHeader

Renders, above the bubble, the MessageReminderHeader override when the message has a reminder with a time, or the MessageSavedForLaterHeader override when it has one without; the MessagePinnedHeader override for a pinned message; and the SentToChannelHeader override for a reply also sent to the channel. It renders nothing when none applies. It reads the message and its reminder from context.

Prop Type Default Description
message LocalMessage from MessageContext Passed to MessagePinnedHeader. Which marks show still follows the message in MessageContext.

MessagePinnedHeader

Renders "Pinned by" and the name of who pinned the message, or "You". It renders nothing for a message that isn't pinned.

Prop Type Default Description
message LocalMessage from MessageContext The message.

MessageReminderHeader

Renders "Reminder set" and the time left, from the duration.messageReminder translation key, or "Reminder overdue". It reads the reminder of the message in MessageContext.

Prop Type Default Description
isReminderTimeLeft boolean true while timeLeftMs is above 0 Picks "Reminder set" over "Reminder overdue".
timeLeftMs number the reminder's timeLeftMs The time until the reminder, in milliseconds.

MessageSavedForLaterHeader

Renders "Saved For Later" with a bookmark icon. It takes no props. The exported MessageSavedForLaterHeaderProps type lists message, which the component doesn't read.

SentToChannelHeader

Renders "Also sent in channel" on a reply shown in a thread, and "Replied to a thread" on the same reply shown in the channel. With onAlsoSentToChannelHeaderPress set on Channel or Thread, it adds View: in a thread, pressing it calls the handler with the message's ID; in a channel, with the message's ID and the reply's Thread, loading the parent message first when it isn't loaded.

Prop Type Default Description
onPress () => void calls onAlsoSentToChannelHeaderPress as described above Called when the user presses View.
showViewText boolean true when onAlsoSentToChannelHeaderPress is set Shows View.
thread Thread from ThreadContext Picks the text: "Also sent in channel" inside a thread.

MessageTextContainer

Renders the message's text as Markdown, with mentions and links that can be pressed. When the message has an auto-translation into the user's language, it renders that instead. It renders nothing for a message without text. With the MessageText override set, it renders that inside its container instead, with its own props, renderText (the exported function it renders with by default) and theme; see Overriding components.

Prop Type Default Description
hasInteractiveAccessibilityContent boolean from MessageContext Makes the text its own accessibility element.
isMyMessage boolean from MessageContext Picks the colors of the user's own messages.
markdownRules MarkdownRules from MessagesContext simple-markdown rules merged over the SDK's.
markdownStyles MarkdownStyle Styles merged over theme.messageItemView.content.markdown.
message LocalMessage from MessageContext The message whose text renders.
messageOverlay boolean Set when the text renders in the message menu. The text then re-renders when markdownStyles change.
messageTextNumberOfLines number from MessagesContext Truncates the text to this many lines, and renders only the first paragraph.
myMessageTheme DeepPartial<Theme> from MessagesContext The text re-renders when it changes.
onLongPress (payload: PressableHandlerPayload) => void from MessageContext Called on a long press on the text.
onlyEmojis boolean from MessageContext Applies the onlyEmojiMarkdown style.
onPress (payload: MessagePressableHandlerPayload) => void from MessageContext Called on a press on a link or a mention, with the textLink or textMention emitter.
preventPress boolean from MessageContext Turns off presses on the text.
styles Partial<{ textContainer: StyleProp<ViewStyle>; }> Style of the view around the text.

MessageFooter

Renders, under the bubble, the sender's name on other users' messages, except in a channel with exactly two members, the MessageStatus override when showMessageStatus is set, the MessageTimestamp override, and "Edited" on an edited message that isn't AI-generated. It renders nothing for a message the server accepted that isn't the last of its group.

Prop Type Default Description
alignment Alignment from MessageContext The sender's name shows on 'left' messages only.
date string | Date The time to show, passed to MessageTimestamp as timestamp. MessageItemView passes the message's created_at.
formattedDate string | Date Text shown in place of the formatted date.
lastGroupMessage boolean from MessageContext With false, the footer shows only on a message that is sending or failed.
message LocalMessage from MessageContext The message.
otherAttachments Attachment[] Not used.
showMessageStatus boolean from MessageContext Shows MessageStatus.

MessageTimestamp

Renders a time formatted with a translation key. It renders nothing when there's no time to show.

Prop Type Default Description
formattedDate string | Date Text shown as is, in place of the formatted timestamp.
tDateTimeParser TDateTimeParser from TranslationContext Parses the time for formatting.
timestamp string | Date The time to format.
timestampTranslationKey string 'timestamp.MessageTimestamp' The translation key whose value is the format. See Date and time formatting.

MessageStatus

Renders the status of one of the user's own messages: a clock while sending, one check once the server accepted it, and two checks once it reached or was read by another member, in a different color when read. It renders nothing for a failed or error message. Read state, unread and receipts explains where the receipts come from.

Prop Type Default Description
delivered boolean useIsMessageDeliveredToOthers({ message }) Whether the message reached at least one other member.
message LocalMessage from MessageContext The message.
read boolean useIsMessageReadByOthers({ message }) Whether at least one other member read the message.

MessageReplies

Renders "1 Reply" or "5 Replies", the MessageRepliesAvatars override and a connector line. It renders nothing for a message without replies. Pressing it reports the messageReplies emitter with onOpenThread as the default handler, so it calls the list's onThreadSelect. MessageItemView doesn't render it inside a thread; a view of your own that renders it checks useThreadContext().thread itself.

Prop Type Default Description
alignment Alignment from MessageContext Puts the connector on the left or the right.
isMyMessage boolean from MessageContext Picks the connector's color.
message LocalMessage from MessageContext The message whose reply_count shows.
onLongPress (payload: PressableHandlerPayload) => void from MessageContext Called on a long press.
onOpenThread () => void from MessageContext The default handler of a press.
onPress (payload: MessagePressableHandlerPayload) => void from MessageContext Called on a press.
onPressIn ((payload: PressableHandlerPayload) => void) | null from MessageContext Called when a press starts.
preventPress boolean from MessageContext Turns off presses.
t StreamTFunction from TranslationContext Translates the label.

MessageRepliesAvatars

Renders the avatars of up to three of the message's thread_participants.

Prop Type Default Description
message LocalMessage from MessageContext The message whose participants show.

MessageDeleted

Renders "Message deleted" in a bubble, and the MessageFooter override under it. MessageItemView renders it in place of the headers, the bubble, the reactions and the replies of a deleted message.

Prop Type Default Description
alignment Alignment from MessageContext Aligns the bubble left or right.
date string | Date Passed to MessageFooter.
groupStyle string required The alignment and group, such as 'left_bottom'. left_bottom, left_single, right_bottom and right_single give the bubble its tail corner.
message LocalMessage from MessageContext The component re-renders when its type, text, status, reply count or pinned state changes.

MessageError

Renders the error badge at the top corner of a failed or error message's bubble. It takes no props.

MessageBlocked

Renders the text of a message that moderation blocked, centered in a pill. Message renders it in place of the message view.

Prop Type Default Description
message LocalMessage required The blocked message. Its text is shown.
style StyleProp<ViewStyle> Style of the container.

MessageBounce

Shows the dialog of a message that moderation bounced: "Send Anyway" resends it, "Edit Message" puts it in the composer, and "Delete Message" removes it from the list. It renders no view of its own, and opens a native alert when it renders. Message renders it when the user presses or long presses a bounced message.

Prop Type Default Description
message LocalMessage from MessageContext The bounced message.
removeMessage (message: { id: string; parent_id?: string; }) => Promise<void> from useMessageOperations() Removes the message locally, for "Delete Message".
retrySendMessage (message: LocalMessage) => Promise<void> from useMessageOperations() Resends the message, for "Send Anyway".
setEditingState (message?: LocalMessage) => void from MessageComposerAPIContext Puts the message in the composer, for "Edit Message".
setIsBounceDialogOpen React.Dispatch<React.SetStateAction<boolean>> required Closes the dialog. Each button calls it with false.

Replacing the bounce alert shows a replacement.

MessageSystem

Renders a system message, such as "Cleo joined the channel", with its time from the timestamp.MessageSystem translation key. The list renders it in place of Message for a message of type system.

Prop Type Default Description
message LocalMessage required The system message.
style StyleProp<ViewStyle> Style of the container. The list passes theme.messageList.messageContainer.

StreamingMessageView

Renders the text of an AI-generated message with MessageTextContainer, revealing new text a few letters at a time as the message updates. The text the message had when it mounted shows at once. MessageContent renders it in place of the text when isMessageAIGenerated on Chat returns true for the message. StreamingMessageView covers the AI setup.

Prop Type Default Description
letterInterval number 0 The delay between steps, in milliseconds.
message LocalMessage from MessageContext The message whose text streams.
renderingLetterCount number 2 The number of letters revealed at each step.
  • useMessageContext() reads the message the parts render.
  • useIsMessageReadByOthers({ message }) and useIsMessageDeliveredToOthers({ message }) give the receipts MessageStatus shows, and useMessageReadData and useMessageDeliveredData who read the message and who received it. See Message hooks.
  • useMessageReminder(messageId) returns the reminder MessageHeader reads.
  • useStreamingMessage({ text }) reveals text the way StreamingMessageView does.