# Channel List UI

[`ChannelList`](/chat/docs/sdk/react/components/core-components/channel-list/) is the primary navigation surface in most chat apps. Even when you want a heavily customized list, it is usually better to build on the SDK list than to reimplement channel events, unread counts, and active-channel wiring yourself.

## Best Practices

- Start from a `WithComponents` override for `ChannelListItemUI` before reaching for `renderChannels`.
- Preserve the row click behavior so the active channel stays in sync with `Channel`.
- Prefer `displayTitle`, `displayImage`, and `latestMessagePreview` from preview props over recomputing everything manually.
- If you build preview text from `useLatestMessagePreview()`, handle native `giphy` messages separately from ordinary images.
- Use `aria-pressed` for the selected row state to match the default preview semantics.
- Keep preview rows lightweight and CSS-driven.

## Custom Channel Preview

The simplest customization point is the `ChannelListItemUI` override:

```tsx
import { ChannelList, WithComponents } from "stream-chat-react";

<WithComponents overrides={{ ChannelListItemUI: CustomChannelListItem }}>
  <ChannelList />
</WithComponents>;
```

Here is a minimal custom row that uses the current preview helpers:

```tsx
import {
  ChannelAvatar,
  ChannelList,
  ChannelListItemTimestamp,
} from "stream-chat-react";

const CustomChannelListItem = ({
  active,
  channel,
  displayImage,
  displayTitle,
  latestMessagePreview,
  onSelect,
  setActiveChannel,
}) => (
  <button
    aria-pressed={active}
    className="channel-preview"
    onClick={(event) => {
      if (onSelect) {
        onSelect(event);
      } else {
        setActiveChannel?.(channel);
      }
    }}
  >
    <ChannelAvatar imageUrl={displayImage} size="xl" userName={displayTitle} />
    <div className="channel-preview__main">
      <div className="channel-preview__header">
        <span>{displayTitle}</span>
        <ChannelListItemTimestamp
          lastMessage={channel.state.latestMessages.at(-1)}
        />
      </div>
      <div className="channel-preview__message">{latestMessagePreview}</div>
    </div>
  </button>
);
```

```css
.channel-preview {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 12px;
  border: 0;
  background: none;
  text-align: left;
}

.channel-preview__main {
  flex: 1;
  min-width: 0;
}

.channel-preview__header {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-weight: 600;
}

.channel-preview__message {
  color: #6b7280;
}
```

## Using Display Helpers

If you need to derive the title or image yourself, use the current helper utilities instead of older channel-instance helpers:

```tsx
import {
  ChannelAvatar,
  getChannelDisplayImage,
  useChannelDisplayName,
} from "stream-chat-react";

const CustomChannelListItem = ({ channel, latestMessagePreview }) => {
  const displayTitle = useChannelDisplayName(channel);
  const displayImage = getChannelDisplayImage(channel);

  return (
    <div>
      <ChannelAvatar
        imageUrl={displayImage}
        size="xl"
        userName={displayTitle}
      />
      <div>{latestMessagePreview}</div>
    </div>
  );
};
```

`useChannelDisplayName()` and `getChannelDisplayImage()` keep direct-message and group-channel fallbacks aligned with the default SDK preview behavior.

If you build your own summary text with `useLatestMessagePreview()`, include a `giphy` branch. Native `giphy` attachments now resolve to their own preview type instead of reusing the generic `image` path.

## Going Deeper

If the preview row props are not enough, the next customization steps are:

1. Replace `ChannelListUI` through `WithComponents` when the container, loading state, or error state needs to change.
2. Wrap the list with a custom layout using `renderChannels`.
3. Replace pagination with a custom `Paginator`.
4. Replace only the preview action surface through `ChannelListItemActionButtons` in `ComponentContext` when the row UI itself can stay close to default.


---

This page was last updated at 2026-05-22T16:32:13.757Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/guides/customization/channel-list-preview/](https://getstream.io/chat/docs/sdk/react/guides/customization/channel-list-preview/).