import { Channel, Chat, MessageComposer, MessageList } from "stream-chat-react";
const App = () => (
<Chat client={client}>
<Channel channel={channel}>
<MessageList />
<MessageComposer />
</Channel>
</Chat>
);Chat
The Chat component wraps your app and provides ChatContext, including the connected StreamChat client, the active channel, query state, and shared SDK configuration.
Best Practices
- Render
Chatonce at the app root so a single client instance is shared. - Create and connect the client outside render loops to avoid reconnect churn.
- Keep
customClassesminimal and include the layout classes your app still depends on. - Use
themeand CSS variables before reaching for heavy wrapper overrides. - Keep collapsible sidebar state in app code if your layout needs it. The SDK does not manage collapsible sidebar open/close state for you.
Basic Usage
Chat does not render UI by itself. Once you have a connected StreamChat client, pass it to Chat and render the SDK components under it.
Any child of Chat can access the shared state through useChatContext():
import { useChatContext } from "stream-chat-react";
const CustomChild = () => {
const { channel, client, setActiveChannel } = useChatContext();
return null;
};Props
| Prop | Description | Type |
|---|---|---|
client | The connected StreamChat client instance. | StreamChat |
customClasses | Custom CSS class names that replace the SDK's default container classes. | CustomClasses |
defaultLanguage | Fallback language for UI translations. Defaults to "en". | SupportedTranslations |
i18nInstance | Custom Streami18n instance for SDK translations. | Streami18n |
isMessageAIGenerated | Callback used by SDK components that need to distinguish AI-generated messages. | (message: LocalMessage) => boolean |
searchController | Optional SearchController instance for the SDK search surfaces. If omitted, Chat creates one with channel, user, and message search sources. | SearchController |
theme | Theme class names added to chat surfaces such as Channel and ChannelList. Defaults to "messaging light". | string |
useImageFlagEmojisOnWindows | Enables the emoji replacement font for country flags on Windows. Import stream-chat-react/css/v2/emoji-replacement.css when enabling it. Defaults to false. | boolean |
Examples
Custom customClasses
import type { CustomClasses } from "stream-chat-react";
const customClasses: CustomClasses = {
channel: "custom-channel-class",
chat: "custom-chat-class",
};
const App = () => (
<Chat client={client} customClasses={customClasses}>
{/* Chat children */}
</Chat>
);Accepted keys and the default classes they replace:
chat->str-chatchatContainer->str-chat__containerchannel->str-chat__channelchannelList->str-chat__channel-listmessage->str-chat__li str-chat__li--${groupStyles}messageList->str-chat__message-listthread->str-chat__thread-container str-chat__threadvirtualMessage->str-chat__virtual-list-message-wrapper str-chat__livirtualizedMessageList->str-chat__virtual-list
Be careful when overriding messageList, thread, or virtualizedMessageList container classes. Those wrappers carry layout rules the SDK relies on for scrolling and virtualization.
Custom i18nInstance
import { Streami18n } from "stream-chat";
const i18nInstance = new Streami18n({ language: "es" });
<Chat client={client} i18nInstance={i18nInstance}>
{/* Chat children */}
</Chat>;Own Sidebar State In App Code
If your app needs a collapsible sidebar, keep that state in your own React state or context and wire it into SDK header slots. Chat no longer owns mobile-nav or sidebar open/close state.
For a fuller implementation, see the Collapsible Sidebar cookbook.
import { useState } from "react";
import {
Channel,
ChannelHeader,
Chat,
MessageComposer,
MessageList,
Window,
WithComponents,
} from "stream-chat-react";
const AppShell = () => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const SidebarToggle = () => (
<button onClick={() => setSidebarOpen((open) => !open)} type="button">
{sidebarOpen ? "Close sidebar" : "Open sidebar"}
</button>
);
return (
<div className={sidebarOpen ? "sidebar-open" : "sidebar-closed"}>
<Chat client={client}>
<WithComponents overrides={{ HeaderStartContent: SidebarToggle }}>
<Channel channel={channel}>
<Window>
<ChannelHeader />
<MessageList />
<MessageComposer />
</Window>
</Channel>
</WithComponents>
</Chat>
</div>
);
};