Hello! I am styled using your active Material UI theme. Try sending a message.
Chat - Slot overrides
Replace individual subcomponents inside ChatBox with your own implementations using the slots and slotProps API.
ChatBox composes many themed subcomponents internally — message bubbles, the composer, the conversation list, date dividers, and more.
The slots prop lets you swap any of them with your own component, while slotProps passes extra props to those components without replacing them.
Basic replacement
Pass a custom component to a named slot. Your component receives the same props that the default component would receive.
Passing extra props with slotProps
Use slotProps to pass additional props to either the default or a custom slot component without replacing them.
Complete slot reference
Layout slots
| Slot name | Default component | Element | Description |
|---|---|---|---|
root |
div |
<div> |
Outermost container |
layout |
div |
<div> |
Arranges conversation + thread panes |
conversationsPane |
div |
<div> |
Conversations sidebar container |
threadPane |
div |
<div> |
Thread (message list + composer) container |
Conversation slots
| Slot name | Default component | Element | Description |
|---|---|---|---|
conversationList |
ChatConversationList |
<div> |
Conversation list |
conversationHeader |
ChatConversationHeader |
<header> |
Header bar above the message list |
conversationTitle |
ChatConversationTitle |
<div> |
Conversation name |
conversationSubtitle |
ChatConversationSubtitle |
<div> |
Secondary line (participants, etc.) |
conversationHeaderActions |
ChatConversationHeaderActions |
<div> |
Action buttons in the header |
Message list slots
| Slot name | Default component | Element | Description |
|---|---|---|---|
messageList |
ChatMessageList |
<div> |
Scrollable message container |
messageRoot |
ChatMessage |
<div> |
Individual message row |
messageAvatar |
ChatMessageAvatar |
<div> |
Author avatar |
messageContent |
ChatMessageContent |
<div> |
Message bubble |
messageMeta |
ChatMessageMeta |
<div> |
Timestamp and delivery status |
messageActions |
ChatMessageActions |
<div> |
Hover action menu |
messageGroup |
ChatMessageGroup |
<div> |
Same-author message group |
dateDivider |
ChatDateDivider |
<div> |
Date separator between groups |
Composer slots
| Slot name | Default component | Element | Description |
|---|---|---|---|
composerRoot |
ChatComposer |
<form> |
Composer container |
composerInput |
ChatComposerTextArea |
<textarea> |
Auto-resizing text area |
composerSendButton |
ChatComposerSendButton |
<button> |
Submit button |
composerAttachButton |
ChatComposerAttachButton |
<button> |
File attach trigger |
composerToolbar |
ChatComposerToolbar |
<div> |
Button row |
composerHelperText |
ChatComposerHelperText |
<div> |
Disclaimer or hint |
Indicator slots
| Slot name | Default component | Element | Description |
|---|---|---|---|
typingIndicator |
ChatTypingIndicator |
<div> |
Animated dots while assistant responds |
unreadMarker |
ChatUnreadMarker |
<div> |
"New messages" marker |
scrollToBottom |
ChatScrollToBottomAffordance |
<button> |
Floating scroll-to-bottom button |
suggestions |
ChatSuggestions |
<div> |
Prompt suggestion chips |
Hiding a slot
Return null from a slot to remove it entirely:
<ChatBox
adapter={adapter}
slots={{
conversationHeader: () => null,
composerAttachButton: () => null,
suggestions: () => null,
}}
/>
For common show/hide needs, prefer the features prop which handles the logic cleanly:
The autoScroll feature flag controls scroll behavior rather than slot visibility:
<ChatBox
adapter={adapter}
features={{
autoScroll: { buffer: 300 }, // Custom threshold (default: 150px)
// autoScroll: false, // Disable auto-scrolling entirely
}}
/>
Feature flags and slot rendering
When a feature flag is set to false, the corresponding slot is not rendered at all — even if you provide a custom component via slots. The feature flag takes precedence:
{/* The custom button does not render because the feature is disabled */}
<ChatBox
adapter={adapter}
features={{ attachments: false }}
slots={{ composerAttachButton: MyCustomButton }} {/* ignored */}
/>
To conditionally show a custom component, keep the feature flag enabled and handle visibility in your slot component instead.
CSS classes
The chatBoxClasses utility object provides class name constants for CSS targeting:
import { chatBoxClasses } from '@mui/x-chat';
// Available: chatBoxClasses.root, chatBoxClasses.layout,
// chatBoxClasses.conversationsPane, chatBoxClasses.threadPane
TypeScript
Import the slot types for type-safe custom components:
import type { ChatBoxSlots, ChatBoxSlotProps } from '@mui/x-chat';
// Your custom slot component receives the same props as the default
const MyMessageContent: ChatBoxSlots['messageContent'] = (props) => {
return <div className="custom-bubble" {...props} />;
};
// Type-safe slotProps
const mySlotProps: ChatBoxSlotProps = {
composerInput: { placeholder: 'Type here...' },
messageList: { sx: { p: 2 } },
};
Combining slots with theme overrides
Slots replace the component entirely, while theme styleOverrides adjust the default component's styles.
You can use both together:
API
See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.