import {
Channel,
ChannelHeader,
MessageInput,
MessageList,
} from "stream-chat-react";
const App = () => (
<Channel channel={channel}>
<ChannelHeader />
<MessageList />
<MessageInput />
</Channel>
);This is beta documentation for Stream Chat React SDK v14. For the latest stable version, see the latest version (v13)
.
ChannelHeader
ChannelHeader renders the active channel title, subtitle, sidebar toggle, and avatar.
Best Practices
- Keep
ChannelHeaderlightweight and move heavier logic into parent components or hooks. - Let
ChannelHeaderderive the title and image from the active channel unless you need explicit overrides. - Use a custom header only when you need additional controls or a different layout.
- Keep the sidebar toggle accessible if your layout uses
ChannelListorThreadList. - Do not assume the default header renders
channel.data.subtitle; v14 derives its subtitle from typing state and online/member status.
Basic Usage
Render ChannelHeader inside Channel:
The default title and image come from the same channel-preview helpers used by ChannelList, so direct messages and group channels get synthesized display information automatically.
Default Behavior
By default, ChannelHeader:
- uses
useChannelPreviewInfo()to derivedisplayTitle,displayImage, and group-avatar members - shows
TypingIndicatorHeaderin the subtitle while other users are typing in the active channel - otherwise shows online/member status text from
useChannelHeaderOnlineStatus() - renders
ChannelAvatar, which falls back to a group avatar when enough members are available
UI Customization
You can override the avatar or menu icon locally:
import {
Avatar,
Channel,
ChannelHeader,
type ChannelAvatarProps,
} from "stream-chat-react";
const CustomAvatar = ({ imageUrl, userName }: ChannelAvatarProps) => (
<Avatar imageUrl={imageUrl} size="lg" userName={userName} />
);
const CustomMenuIcon = () => <span aria-hidden="true">≡</span>;
<Channel channel={channel}>
<ChannelHeader Avatar={CustomAvatar} MenuIcon={CustomMenuIcon} />
</Channel>;If you need to replace the whole header, render your own component instead of ChannelHeader. For example, a custom header can still reuse useChannelPreviewInfo() and TypingIndicatorHeader:
import {
TypingIndicatorHeader,
useChannelPreviewInfo,
useChannelStateContext,
useTypingContext,
} from "stream-chat-react";
const CustomChannelHeader = () => {
const { channel, channelConfig } = useChannelStateContext();
const { typing } = useTypingContext();
const { displayTitle } = useChannelPreviewInfo({ channel });
const hasTyping =
channelConfig?.typing_events !== false &&
Object.values(typing ?? {}).some(({ parent_id }) => !parent_id);
return (
<div className="custom-channel-header">
<div>{displayTitle}</div>
<div>{hasTyping ? <TypingIndicatorHeader /> : "Custom subtitle"}</div>
</div>
);
};Props
| Prop | Description | Type |
|---|---|---|
Avatar | Custom avatar component. It receives the same props as ChannelAvatar. Defaults to ChannelAvatar. | component |
image | Manual image override. When omitted, ChannelHeader uses the current channel display image. | string |
MenuIcon | Custom menu icon component used by the sidebar toggle button. Defaults to IconLayoutAlignLeft. | component |
title | Manual title override. When omitted, ChannelHeader uses the current channel display title. | string |