<Chat client={client}>
<ChannelList />
<Channel>
<Window>
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>Thread
Thread renders replies for a parent message. It maintains its own state and renders its own MessageList and MessageInput. You can override UI via props or ComponentContext.
Thread consumes the contexts from Channel and has no required props.
Best Practices
- Always wrap main content in
Windowto keep layout stable when threads open. - Use thread-specific
Message/MessageInputonly when UX truly diverges. - Keep thread UI consistent with the main channel for familiarity.
- Use
virtualizedfor long-running or high-traffic threads. - Avoid over-customizing
ThreadHeader/ThreadStartunless needed.
Basic Usage
Thread must be rendered under Channel. For smooth mount/unmount, wrap the main channel UI in Window, which handles layout changes when the thread opens.
UI Customization
Thread uses most of the same pieces as Channel, so customization works similarly. You can override the thread’s Message and MessageInput via props, and override ThreadHeader/ThreadStart via ComponentContext.
Example 1 - Render different UI for the thread and the main channel.
A common pattern is: check props first, then fall back to context.
const MainInput = (props) => {
// render main `MessageInput` UI component here
};
const MainMessage = (props) => {
// render main `Message` UI component here
};
const ThreadInput = (props) => {
// render thread `MessageInput` UI component here
};
const ThreadMessage = (props) => {
// render thread `Message` UI component here
};
<Chat client={client}>
<ChannelList />
<Channel Input={MainInput} Message={MainMessage}>
<Window>
<MessageList />
<MessageInput />
</Window>
<Thread Input={ThreadInput} Message={ThreadMessage} />
</Channel>
</Chat>;Example 2 - Provide custom UI for ThreadHeader and ThreadStart. ThreadHeader renders above the parent message, and ThreadStart separates the parent message from the reply list.
const CustomThreadHeader = (props) => {
// render thread header UI component here
};
const CustomThreadStart = (props) => {
// render thread start UI component here
};
<Chat client={client}>
<ChannelList />
<Channel ThreadHeader={CustomThreadHeader} ThreadStart={CustomThreadStart}>
<Window>
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>;Example 3 - Customize the parent message + ThreadStart separator by providing a ThreadHead component on Channel. It’s stored in ComponentContext['ThreadHead'].
const CustomThreadHead = (props) => {
// render thread header UI component here
};
<Chat client={client}>
<ChannelList />
<Channel ThreadHead={CustomThreadHead} ThreadStart={CustomThreadStart}>
<Window>
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>;Props
additionalMessageInputProps
Additional props to be passed to the underlying MessageInput component.
| Type |
|---|
| object |
additionalMessageListProps
Additional props to be passed to the underlying MessageList component.
| Type |
|---|
| object |
additionalParentMessageProps
Additional props to be passed to the underlying Message component, which represents the
thread's parent message.
| Type |
|---|
| object |
additionalVirtualizedMessageListProps
Additional props for VirtualizedMessageList component.
| Type |
|---|
| object |
autoFocus
If true, focuses the MessageInput component on opening a thread.
| Type | Default |
|---|---|
| boolean | true |
enableDateSeparator
Controls injection of DateSeparator UI component into underlying MessageList or VirtualizedMessageList.
| Type | Default |
|---|---|
| boolean | false |
Input
Custom UI component to replace the MessageInput of a Thread. The component uses MessageInputFlat by default.
| Type | Default |
|---|---|
| component | MessageInputFlat |
Message
Custom thread message UI component used to override the default Message value stored in ComponentContext.
| Type | Default |
|---|---|
| component | ComponentContext['Message'] |
messageActions
Array of allowed message actions (ex: 'edit', 'delete', 'reply'). To disable all actions, provide an empty array.
| Type | Default |
|---|---|
| array | ['edit', 'delete', 'flag', 'markUnread', 'mute', 'pin', 'quote', 'react', 'remindMe', 'reply', 'saveForLater'] |
It is also possible to display actions that are by default supported by the SDK, but not active by default:
import {
Thread,
MESSAGE_ACTIONS,
OPTIONAL_MESSAGE_ACTIONS,
} from "stream-chat-react";
const messageActions = [
...Object.keys(MESSAGE_ACTIONS),
OPTIONAL_MESSAGE_ACTIONS.deleteForMe, // has to be explicitly added to the messageActions array
];
<Thread messageActions={messageActions} />;virtualized
If true, render the VirtualizedMessageList instead of the standard MessageList component.
| Type |
|---|
| boolean |