import { Avatar, type ThreadHeaderProps } from "stream-chat-react";
export const CustomThreadHeader = ({
closeThread,
overrideTitle,
thread,
}: ThreadHeaderProps) => {
const replyCount = thread.reply_count ?? 0;
const participants = thread.thread_participants ?? [];
return (
<div className="thread-header">
<div className="thread-header__participants">
{participants.map((participant) => (
<Avatar
imageUrl={participant.image}
key={participant.id}
size="sm"
userName={participant.name ?? participant.id}
/>
))}
</div>
<div className="thread-header__content">
<div className="thread-header__title">{overrideTitle ?? "Thread"}</div>
<div className="thread-header__subtitle">{replyCount} replies</div>
</div>
<button onClick={() => closeThread()}>Close</button>
</div>
);
};This is beta documentation for Stream Chat React SDK v14. For the latest stable version, see the latest version (v13)
.
Thread Header
This example shows how to build a custom ThreadHeader.
Best Practices
- Keep thread headers compact so the thread message list keeps as much vertical space as possible.
- Derive the display title from the current channel or parent message instead of duplicating thread state.
- Use current avatar props (
imageUrl,userName,size) in custom participant UI. - Treat the close button as optional when the thread is rendered through a thread instance.
- Keep typing behavior in the subtitle, not in the main title row.
Create The Component
The default ThreadHeader renders a fixed title (Thread) and a subtitle based on the current channel display name plus reply count, or typing state when someone is typing in the thread.
You can build your own header with the current ThreadHeaderProps:
.thread-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.thread-header__participants {
display: flex;
gap: 6px;
}
.thread-header__content {
flex: 1;
min-width: 0;
}
.thread-header__title {
font-weight: 600;
}
.thread-header__subtitle {
color: #6b7280;
font-size: 0.875rem;
}Register The Override
ThreadHeader is now a ComponentContext override. Register it with WithComponents:
import {
Channel,
MessageInput,
MessageList,
Thread,
WithComponents,
} from "stream-chat-react";
const App = () => (
<WithComponents overrides={{ ThreadHeader: CustomThreadHeader }}>
<Channel>
<MessageList />
<MessageInput />
<Thread />
</Channel>
</WithComponents>
);If you need the SDK's current subtitle behavior in a custom header, reuse TypingIndicatorHeader for typing state and useChannelPreviewInfo() for the channel display title.