# Channel UI

> **Info:** This is release candidate documentation for **Stream Chat React SDK v15**. For the latest stable version, see the [latest version (v14)](https://getstream.io/chat/docs/sdk/react/).

An open channel is a column of parts: a header, a message list and a composer. `Channel` gives one channel to every part inside it, and the parts are yours to choose. This page covers `Channel` itself, the channel header, the typing indicator and channel details. The props are in the [Channel](https://getstream.io/chat/docs/sdk/react/v15/component-reference/channel/channel/) and [ChannelHeader](https://getstream.io/chat/docs/sdk/react/v15/component-reference/channel/channelheader/) references.

## The Channel component

`<Channel channel={channel}>` binds a channel to its children:

- It gives the channel to the components inside. They read it with `useChannel()`. `MessageList` renders `channel.messagePaginator`, and `MessageComposer` writes into `channel.messageComposer`.
- It activates the channel while it is mounted, which tells the client the channel is in use. [Entity lifecycle](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/entity-lifecycle/) explains what that keeps in memory.
- It refreshes the channel's unread snapshot, which the unread separator and the unread notification render from. A channel that was open before isn't queried again, so this is what keeps them right when the user comes back to it.
- It renders the channel's container, `.str-chat__channel`, around the children.
- It gives the channel its own audio players, for voice recordings and audio attachments. When `Channel` unmounts or its `channel` changes, it stops them, so audio from the channel the user left doesn't keep playing.

`Channel` doesn't load the channel. Pass a channel that is already watched, for example with `Channel.watch()`, as in [Show one channel](https://getstream.io/chat/docs/sdk/react/v15/getting-started/quick-start/#show-one-channel). With `ChatView`, `ChannelSlot` renders `Channel` for the channel in its slot.

`ChannelPlaceholder` renders the same container with no channel, for the space a channel fills while none is selected:

```tsx title="src/ChannelPanel.tsx"
import type { Channel as StreamChannel } from "stream-chat";
import {
  Channel,
  ChannelHeader,
  ChannelPlaceholder,
  MessageComposer,
  MessageList,
} from "stream-chat-react";

export const ChannelPanel = ({ channel }: { channel?: StreamChannel }) => {
  if (!channel) {
    return (
      <ChannelPlaceholder>Pick a channel to start chatting.</ChannelPlaceholder>
    );
  }

  return (
    <Channel channel={channel}>
      <ChannelHeader />
      <MessageList />
      <MessageComposer />
    </Channel>
  );
};
```

[How components connect to state](https://getstream.io/chat/docs/sdk/react/v15/ui/how-components-connect-to-state/) explains the contexts `Channel` provides.

## The header

`ChannelHeader` shows the channel from `useChannel()`. From start to end:

1. **`StartContent`**, by default the back button, `WorkspaceNavigationBackButton`. It shows only when the channel is stacked over other content in its panel, and goes back to what is beneath.
2. **The title**: the channel's name. A channel without one shows the other member's name in a direct message, and two other members' names in a group. The `title` prop replaces it.
3. **The subtitle**: who is typing. Otherwise "Online" or "Offline" in a direct message, and "12 members · 3 online" in a group, where online counts the channel's watchers.
4. **The avatar**: the channel image, or its members' avatars, drawn by `ChannelAvatar`. The `image` prop replaces the image, and the `Avatar` prop replaces the component. The default avatar doesn't open channel details; see [Channel details](#channel-details).
5. **`EndContent`**, by default the close button, `WorkspaceNavigationCloseButton`. It shows only when the channel's panel can be closed, which the main channel's panel can't.

![The default channel header](https://getstream.io/docs-assets/images/d42c18b2e60a.png)

Both buttons come from the layout. Without one, neither renders. [Moving between channels, threads and messages](https://getstream.io/chat/docs/sdk/react/v15/ui/layout/moving-between-channels-threads-and-messages/) explains back and close.

A component passed as `StartContent` or `EndContent` replaces the button. To add something and keep the button, render the button yourself:

```tsx title="src/ChannelHeaderWithCall.tsx"
import {
  ChannelHeader,
  useChannel,
  WorkspaceNavigationCloseButton,
} from "stream-chat-react";

const HeaderEnd = () => {
  const channel = useChannel();

  return (
    <>
      <button
        onClick={() => console.log("Start a call in", channel.cid)}
        type="button"
      >
        Call
      </button>
      <WorkspaceNavigationCloseButton />
    </>
  );
};

export const ChannelHeaderWithCall = () => (
  <ChannelHeader EndContent={HeaderEnd} />
);
```

## Typing indicator

Two components show who is typing:

- `TypingIndicator` renders at the bottom of `MessageList`: the avatars of the people typing and animated dots. It shows only while the list is scrolled to the latest message, and announces who is typing to screen readers. `VirtualizedMessageList` renders it only when you register a `TypingIndicator` override.
- `TypingIndicatorHeader` is the "Cleo is typing" text that replaces the header's subtitle.

Both read the same data. The channel keeps the latest typing event of each user in `channel.state.typing` and copies it into its composer, `channel.messageComposer.textComposer.state.typing`. The indicators read it from the composer that `useMessageComposerController()` returns. They leave out the current user and replies typed in threads, and keep showing for two seconds after typing stops, so they don't flicker. Inside a `Thread` they read the thread's composer, which receives no typing events, so they show nothing there. They render nothing when typing events are turned off for the channel (`typingEvents.enabled` in its configuration).

[Typing indicators](https://getstream.io/chat/docs/sdk/react/v15/features/messaging/typing-indicators/) covers the feature end to end: sending typing events and building your own indicator.

## Channel details

Channel details is a panel with the channel's info, members, pinned messages, photos and videos, and files. It lives in its own entry point, `stream-chat-react/channel-detail`, with its own stylesheet.

The entry is the avatar, once you wire it in: `ChannelHeader` doesn't do it by default. `AvatarWithChannelDetail` renders the channel avatar as a button, and clicking it opens `ChannelDetail` in a modal. Pass it to the header as its avatar:

```tsx title="src/ChannelWithDetails.tsx"
import {
  Channel,
  ChannelHeader,
  MessageComposer,
  MessageList,
} from "stream-chat-react";
import { AvatarWithChannelDetail } from "stream-chat-react/channel-detail";
import "stream-chat-react/dist/css/index.css";
import "stream-chat-react/dist/css/channel-detail.css";

export const ChannelWithDetails = () => (
  <Channel channel={channel}>
    <ChannelHeader Avatar={AvatarWithChannelDetail} />
    <MessageList />
    <MessageComposer />
  </Channel>
);
```

The button is disabled until the channel exists on the server, because the details are loaded from there. The modal is the `Modal` override, by default the SDK's `GlobalModal`.

`ChannelDetail` is a section navigator with five sections, in this order: channel info, members, pinned messages, photos and videos, and files. Its `sections` prop chooses and orders them; `defaultChannelDetailSections` is the default list. The navigator picks its layout from the width it has:

- **Tabs**, at 640px and wider: the list of sections beside the open section.
- **Inline**, when narrower: one section at a time, with a menu button in its header that opens the list of sections.

A view inside a section, such as one member's details, opens on top of the section and shows a back button.

To show details in a panel of your own instead of a modal, render `<ChannelDetail channel={channel} />` there. The actions in channel details are action sets, covered in [Actions](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/actions/). The props are in the [Channel Detail reference](https://getstream.io/chat/docs/sdk/react/v15/component-reference/channel-detail/channel-detail/).

## Replacing parts

`Channel` renders only its children, so you replace a part of the channel by rendering a different component in its place. A header of your own can read the channel with `useChannel()`; see the [Channel header recipe](https://getstream.io/chat/docs/sdk/react/v15/recipes/headers/channel-header/).

`ChannelHeader` has no override key. Change it through its props:

| Prop           | Replaces             |
| -------------- | -------------------- |
| `StartContent` | The back button      |
| `EndContent`   | The close button     |
| `Avatar`       | The avatar component |
| `title`        | The title            |
| `image`        | The avatar image     |

The parts on this page that render from an override key:

| Override key      | Replaces                                                            |
| ----------------- | ------------------------------------------------------------------- |
| `TypingIndicator` | The typing indicator in the message lists                           |
| `Modal`           | The modal that channel details open in, and other modals in the SDK |

The message list and the composer have keys of their own, listed on [Message list UI](https://getstream.io/chat/docs/sdk/react/v15/ui/components/message-list-ui/#replacing-parts) and [Message composer UI](https://getstream.io/chat/docs/sdk/react/v15/ui/components/message-composer-ui/#replacing-parts). [Overriding components](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/overriding-components/) explains how overrides apply.

## Used in

- [Channel details and members](https://getstream.io/chat/docs/sdk/react/v15/features/channels/channel-details-and-members/)
- [Typing indicators](https://getstream.io/chat/docs/sdk/react/v15/features/messaging/typing-indicators/)
- [Channel header](https://getstream.io/chat/docs/sdk/react/v15/recipes/headers/channel-header/)

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v15/ui/components/channel-ui/](https://getstream.io/chat/docs/sdk/react/v15/ui/components/channel-ui/).