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 ChannelHeader lightweight and move heavier logic into parent components or hooks.
  • Let ChannelHeader derive 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 ChannelList or ThreadList.
  • 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:

import {
  Channel,
  ChannelHeader,
  MessageInput,
  MessageList,
} from "stream-chat-react";

const App = () => (
  <Channel channel={channel}>
    <ChannelHeader />
    <MessageList />
    <MessageInput />
  </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 derive displayTitle, displayImage, and group-avatar members
  • shows TypingIndicatorHeader in 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

PropDescriptionType
AvatarCustom avatar component. It receives the same props as ChannelAvatar. Defaults to ChannelAvatar.component
imageManual image override. When omitted, ChannelHeader uses the current channel display image.string
MenuIconCustom menu icon component used by the sidebar toggle button. Defaults to IconLayoutAlignLeft.component
titleManual title override. When omitted, ChannelHeader uses the current channel display title.string