# Message UI

The Message UI component consumes [`MessageContext`](/chat/docs/sdk/react/v13/components/contexts/message_context/) and renders a message. It’s typically composed of smaller subcomponents (text, reactions, etc.) that also consume `MessageContext`.

Each message list uses a default Message UI component. If you don’t supply one, [MessageSimple](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageSimple.tsx) is used.

## Best Practices

- Start by composing existing subcomponents instead of building from scratch.
- Use `useMessageContext` in custom UI to avoid prop-drilling.
- Keep option buttons consistent between channel and thread UIs.
- Prefer list-level overrides (`MessageList`/`Thread`) over global defaults when scoped.
- Reuse `MessageSimple` structure as a baseline for accessibility and layout.

## Basic Usage

**Example 1** - Add Message UI component to `MessageList`.

To use your own Message UI in `MessageList`, pass `Message` to `Channel`, `MessageList`, or `Thread`. `Channel` sets a default in `ComponentContext`, while `MessageList`/`Thread` override that value. If both are set, the list-level prop wins.

```tsx
const CustomMessage = () => {
  // consume `MessageContext` and render custom component here
};

<Chat client={client}>
  <Channel channel={channel} Message={CustomMessage}>
    <MessageList />
    <MessageInput />
  </Channel>
</Chat>;
```

**Example 2** - Add Message UI component to `VirtualizedMessageList`.

For `VirtualizedMessageList`, pass `VirtualMessage` on `Channel` or `Message` on `VirtualizedMessageList`. `Channel` sets a default in context, and the list-level prop overrides it. `FixedHeightMessage` is still available but is no longer the default.

```tsx
const CustomMessage = () => {
  // consume `MessageContext` and render custom component here
};

<Chat client={client}>
  <Channel channel={channel} VirtualMessage={CustomMessage}>
    <VirtualizedMessageList />
    <MessageInput />
  </Channel>
</Chat>;
```

## UI Customization

`MessageSimple` and `FixedHeightMessage` are meant as guides. They compose smaller UI pieces that each handle a specific part of message rendering.

If we strip `MessageSimple` down to its core pieces, the component resembles the following snippet:

```tsx {14,16,17,18,19,20}
<div>
  <MessageStatus />
  <Avatar />
  <div>
    <MessageOptions />
    <div>
      <ReactionsList />
      <ReactionSelector />
    </div>
    <div>
      <Attachment />
      <MessageText />
      <MessageErrorIcon />
    </div>
  </div>
  <MessageRepliesCountButton />
  <div>
    <MessageTimestamp />
  </div>
</div>
```

We recommend following a similar pattern: mix and match the exported subcomponents to suit your layout. Each subcomponent reads from `MessageContext` and requires little or no props.

For a detailed example, review the [Message UI Customization](/chat/docs/sdk/react/v13/guides/theming/message_ui/) example.

### Message options

The default Message UI renders three option buttons next to the message content:

1. button to open message actions drop-down menu - message actions box
2. button to open thread
3. button to open reaction selector

In a thread, the “open thread” button is omitted.

#### Message actions box

The menu contains default actions based on user permissions. You can also add [custom actions](/chat/docs/sdk/react/v13/components/message-components/message_ui/#custommessageactions/), which appear as extra menu items.

## Props

<admonition type="note">

All Message UI props override values from [`MessageContext`](/chat/docs/sdk/react/v13/components/contexts/message_context/). For custom components, prefer `useMessageContext`. If you build on `MessageSimple`, you can override individual props as needed.

</admonition>

### actionsEnabled

If true, actions such as edit, delete, flag, etc. are enabled on the message (overrides the value stored in `MessageContext`).

| Type    | Default |
| ------- | ------- |
| boolean | true    |

### additionalMessageInputProps

Additional props to be passed to the underlying [`MessageInput`](/chat/docs/sdk/react/v13/components/message-input-components/message_input/) component that's rendered
while editing (overrides the value stored in `MessageContext`).

| Type   |
| ------ |
| object |

### autoscrollToBottom

Call this function to keep the list pinned to the bottom when its scroll height increases (only in `VirtualizedMessageList`). It won’t auto-scroll if the user is more than 4px away from the bottom.

You can even use the function to keep the container scrolled to the bottom while images are loading:

```tsx
const Image = (props: ImageProps) => {
  ...
  const { autoscrollToBottom } = useMessageContext();
  ...

  return (
    <img
      ...
      onLoad={autoscrollToBottom}
      ...
    />
  );
};
```

| Type       |
| ---------- |
| () => void |

### clearEditingState

When called, this function will exit the editing state on the message (overrides the function stored in `MessageContext`).

| Type                                       |
| ------------------------------------------ |
| (event?: React.BaseSyntheticEvent) => void |

### customMessageActions

An object containing custom message actions (key) and function handlers (value) (overrides the value stored in `MessageContext`). The key is used as a display text inside the button. Therefore, it should not be cryptic but rather bear the end user in mind when formulating it.

```tsx
const customActions = {
  "Copy text": (message) => {
    navigator.clipboard.writeText(message.text || "");
  },
};

<MessageList customMessageActions={customActions} />;
```

Custom action item "Copy text" in the message actions box:

![Image of a custom action item ](@chat-sdk/react/v13/_assets/message-actions-box-custom-actions.png)

| Type   |
| ------ |
| object |

### deliveredTo

An array of user IDs that have confirmed the message delivery to their device.

| Type             |
| ---------------- |
| `UserResponse[]` |

### editing

If true, the message toggles to an editing state (overrides the value stored in `MessageContext`).

| Type    | Default |
| ------- | ------- |
| boolean | false   |

### formatDate

Overrides the default date formatting logic, has access to the original date object (overrides the function stored in `MessageContext`).

| Type                   |
| ---------------------- |
| (date: Date) => string |

### getMessageActions

Function that returns an array of the allowed actions on a message by the currently connected user (overrides the function stored in `MessageContext`).

| Type                      |
| ------------------------- |
| () => MessageActionsArray |

### groupByUser

If true, group messages sent by each user (only used in the `VirtualizedMessageList`).

| Type    | Default |
| ------- | ------- |
| boolean | false   |

### groupStyles

An array of potential styles to apply to a grouped message (ex: top, bottom, single) (overrides the value stored in `MessageContext`).

| Type     | Options                                         |
| -------- | ----------------------------------------------- |
| string[] | '' \| 'middle' \| 'top' \| 'bottom' \| 'single' |

### handleAction

Function that calls an action on a message (overrides the function stored in `MessageContext`).

| Type                                                                                                   | Default                                                                                                          |
| ------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `(dataOrName?: string \| FormData, value?: string, event?: React.BaseSyntheticEvent) => Promise<void>` | [MessageContextValue['handleAction']](/chat/docs/sdk/react/v13/components/contexts/message_context#handleaction) |

### handleDelete

Function that removes a message from the current channel (overrides the function stored in `MessageContext`).

| Type                                                                                         | Default                                                                                                          |
| -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent, options?: DeleteMessageOptions) => Promise<void> \| void` | [MessageContextValue['handleDelete']](/chat/docs/sdk/react/v13/components/contexts/message_context#handledelete) |

### handleEdit

Function that edits a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                      |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handleEdit']](/chat/docs/sdk/react/v13/components/contexts/message_context#handleedit) |

### handleFetchReactions

Function that loads the reactions for a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                                               |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handleFetchReactions']](/chat/docs/sdk/react/v13/components/contexts/message_context#handlhandlefetchreactions) |

This function limits the number of loaded reactions to 1200. To customize this behavior, you can pass [a custom `ReactionsList` component](/chat/docs/sdk/react/v13/components/message-components/reactions#handlefetchreactions/).

### handleFlag

Function that flags a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                      |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handleFlag']](/chat/docs/sdk/react/v13/components/contexts/message_context#handleflag) |

### handleMarkUnread

Function that marks the message and all the following messages as unread in a channel. (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                                  |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handleMarkUnread']](/chat/docs/sdk/react/v13/components/contexts/message_context#handleMarkUnread) |

### handleMute

Function that mutes the sender of a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                      |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handleMute']](/chat/docs/sdk/react/v13/components/contexts/message_context#handlemute) |

### handleOpenThread

Function that opens a [`Thread`](/chat/docs/sdk/react/v13/components/core-components/thread/) on a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                                  |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handleOpenThread']](/chat/docs/sdk/react/v13/components/contexts/message_context#handleopenthread) |

### handlePin

Function that pins a message in the current channel (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                    |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handlePin']](/chat/docs/sdk/react/v13/components/contexts/message_context#handlepin) |

### handleReaction

Function that adds a reaction on a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                              |
| ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['handleReaction']](/chat/docs/sdk/react/v13/components/contexts/message_context#handlereaction) |

### handleRetry

Function that retries sending a message after a failed request (overrides the function stored in `ChannelActionContext`).

| Type                                       | Default                                                                                                                               |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `(message: LocalMessage) => Promise<void>` | [ChannelActionContextValue['retrySendMessage']](/chat/docs/sdk/react/v13/components/contexts/channel_action_context#retrysendmessage) |

### initialMessage

When true, signifies the message is the parent message in a thread list (overrides the value stored in `MessageContext`).

| Type    | Default |
| ------- | ------- |
| boolean | false   |

### isMyMessage

Function that returns whether a message belongs to the current user (overrides the function stored in `MessageContext`).

| Type          |
| ------------- |
| () => boolean |

### isReactionEnabled (deprecated)

If true, sending reactions is enabled in the currently active channel (overrides the value stored in `MessageContext`).

| Type    | Default |
| ------- | ------- |
| boolean | true    |

### lastReceivedId

The latest message ID in the current channel (overrides the value stored in `MessageContext`).

| Type   |
| ------ |
| string |

### message

The `StreamChat` message object, which provides necessary data to the underlying UI components (overrides the value stored in `MessageContext`).

| Type   |
| ------ |
| object |

### messageListRect

DOMRect object linked to the parent `MessageList` component (overrides the value stored in `MessageContext`).

| Type    |
| ------- |
| DOMRect |

### mutes

An array of users that have been muted by the connected user (overrides the value stored in `MessageContext`).

| Type   | Default                                                                                            |
| ------ | -------------------------------------------------------------------------------------------------- |
| Mute[] | [ChannelStateContext['mutes']](/chat/docs/sdk/react/v13/components/contexts/channel_state_context) |

### onMentionsClickMessage

Function that runs on click of an @mention in a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                                                     |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['onMentionsClickMessage']](/chat/docs/sdk/react/v13/components/contexts/channel_action_context#onmentionsclickmessage) |

### onMentionsHoverMessage

Function that runs on hover of an @mention in a message (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                                                     |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['onMentionsHoverMessage']](/chat/docs/sdk/react/v13/components/contexts/channel_action_context#onmentionshovermessage) |

### onUserClick

Function that runs on click of a user avatar (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                               |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['onUserClick']](/chat/docs/sdk/react/v13/components/contexts/channel_action_context#onuserclick) |

### onUserHover

Function that runs on hover of a user avatar (overrides the function stored in `MessageContext`).

| Type                                                         | Default                                                                                                               |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` | [MessageContextValue['onUserHover']](/chat/docs/sdk/react/v13/components/contexts/channel_action_context#onuserhover) |

### pinPermissions

The user roles allowed to pin messages in various channel types (deprecated in favor of `channelCapabilities`).

| Type   | Default                                                                                                              |
| ------ | -------------------------------------------------------------------------------------------------------------------- |
| object | [defaultPinPermissions](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/utils.tsx) |

### readBy

An array of users that have read the current message (overrides the value stored in `MessageContext`).

| Type  |
| ----- |
| array |

### renderText

Custom function to render message text content (overrides the function stored in `MessageContext`).

| Type     | Default                                                                                                                   |
| -------- | ------------------------------------------------------------------------------------------------------------------------- |
| function | [renderText](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/renderText/renderText.tsx) |

### setEditingState

Function to toggle the editing state on a message (overrides the function stored in `MessageContext`).

| Type                                                         |
| ------------------------------------------------------------ |
| `(event: React.BaseSyntheticEvent) => Promise<void> \| void` |

### threadList

If true, indicates that the current `MessageList` component is part of a `Thread` (overrides the value stored in `MessageContext`).

| Type    | Default |
| ------- | ------- |
| boolean | false   |

### unsafeHTML

If true, renders HTML instead of markdown. Posting HTML is only supported server-side (overrides the value stored in `MessageContext`).

| Type    | Default |
| ------- | ------- |
| boolean | false   |


---

This page was last updated at 2026-04-21T07:55:45.118Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v13/components/message-components/message_ui/](https://getstream.io/chat/docs/sdk/react/v13/components/message-components/message_ui/).