Which component should I use for the message input area?
Chat - Multi-conversation
A two-pane inbox layout with a conversation sidebar and an active thread pane.
This demo shows how to use ChatBox as a full inbox surface with multiple conversations.
The conversation sidebar is rendered automatically when more than one conversation is provided.
- A two-pane layout with a conversation list on the left and the active thread on the right
- Controlled
activeConversationIdwithonActiveConversationChangefor conversation switching - Controlled
messagesandonMessagesChangefor per-conversation message state conversationswithunreadCountandreadStatereflected in the sidebar
Controlled vs. uncontrolled conversations
This demo uses controlled state so each conversation keeps its own message history:
const [activeConversationId, setActiveConversationId] = React.useState('thread-a');
const [threads, setThreads] = React.useState({ 'thread-a': [], 'thread-b': [] });
<ChatBox
activeConversationId={activeConversationId}
messages={threads[activeConversationId] ?? []}
onActiveConversationChange={(nextId) => setActiveConversationId(nextId)}
onMessagesChange={(nextMessages) => {
setThreads((prev) => ({ ...prev, [activeConversationId]: nextMessages }));
}}
/>;
For simpler use cases with a single conversation, use initialActiveConversationId and initialMessages instead.
Conversation list behavior
The conversation list renders automatically when conversations contains more than one item.
If only one conversation is provided, ChatBox renders the thread pane directly without a sidebar.
Implementation notes
- Store message threads in a
Record<string, ChatMessage[]>keyed byconversationId. - Sync conversation previews after messages change using
onMessagesChange. - The
unreadCountandreadStateon each conversation drive the sidebar badge and read indicator.
See also
- Custom theme to apply brand colors across the entire surface
- Customization for
slotPropson the conversation list and thread header