const CustomChannelHeader = (props: ChannelHeaderProps) => {
const { title } = props;
const { channel } = useChannelStateContext();
const { name } = channel.data || {};
return <div>{title || name}</div>;
};Channel Header
This example shows how to use a custom ChannelHeader. Unlike most components that are overridden via props, you can just render your custom header in place of the default.
Best Practices
- Keep header UI lightweight to avoid re-render overhead.
- Pull channel data from
ChannelStateContextviauseChannelStateContextinstead of duplicating state. - Use
TypingIndicatorthoughtfully to avoid noisy headers. - Remove the default typing indicator if you render a custom one.
- Preserve accessibility for channel title and controls.
Implementation
The default header displays the channel name, member count, and online count. In this example, we render the name and add a typing indicator below. Because the custom header is a child of Channel, it can access channel via ChannelStateContext and useChannelStateContext.
Next, add the typing indicator to the header and remove the default one in MessageList by overriding it with a null component.
const CustomChannelHeader = (props: ChannelHeaderProps) => {
const { title } = props;
const { channel } = useChannelStateContext();
const { name } = channel.data || {};
return (
<>
<div>{title || name}</div>
<TypingIndicator />
</>
)
}
<Channel TypingIndicator={() => null}>You can render additional header details by pulling more data from channel. For this demo, we’ll add some basic styling.
.header-title {
padding: 5px 7px;
}
.header-pound {
color: #006cff;
font-weight: 800;
padding-right: 2px;
}const CustomChannelHeader = (props: ChannelHeaderProps) => {
const { title } = props;
const { channel } = useChannelStateContext();
const { name } = channel.data || {};
return (
<div className="str-chat__header-livestream">
<div>
<div className="header-item">
<span className="header-pound">#</span>
{title || name}
</div>
<TypingIndicator />
</div>
</div>
);
};The Final Code
Finally, render the custom header where the default would normally appear.
.header-title {
padding: 5px 7px;
}
.header-pound {
color: #006cff;
font-weight: 800;
padding-right: 2px;
}const CustomChannelHeader = (props: ChannelHeaderProps) => {
const { title } = props;
const { channel } = useChannelStateContext();
const { name } = channel.data || {};
return (
<div className="str-chat__header-livestream">
<div>
<div className="header-item">
<span className="header-pound">#</span>
{title || name}
</div>
<TypingIndicator />
</div>
</div>
);
};const App = () => (
<Chat client={chatClient}>
<ChannelList />
<Channel TypingIndicator={() => null}>
<Window>
<CustomChannelHeader />
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</Chat>
);The Result
