Hello! I am styled using your active Material UI theme. Try sending a message.
Chat - Model selector
Add a model picker to the conversation header using the conversationHeaderActions slot.
This demo shows how to place a MUI Select inside the conversation header so users can switch between AI models.
No new component is needed — drop any MUI control into slots.conversationHeaderActions.
slots.conversationHeaderActionsaccepting a custom component that renders aSelect- Controlled model state owned by the selector component
- The
Selectplaced inline in the header viamarginInlineStart: 'auto'(applied automatically byChatConversationHeaderActions)
Press Enter to start editing
The pattern
function MyModelSelector() {
const [model, setModel] = React.useState('gpt-4o');
return (
<Select value={model} onChange={(e) => setModel(e.target.value)} size="small">
<MenuItem value="gpt-4o">GPT-4o</MenuItem>
<MenuItem value="claude-3-5-sonnet">Claude 3.5 Sonnet</MenuItem>
</Select>
);
}
<ChatBox slots={{ conversationHeaderActions: MyModelSelector }} />;
Passing the model to the adapter
The demo above keeps model state inside the selector.
To also pass the selected model to adapter.sendMessage, hoist state up to the parent and construct the adapter with React.useMemo:
export default function App() {
const [model, setModel] = React.useState('gpt-4o');
const adapter = React.useMemo(
() => ({
async sendMessage({ message, signal }) {
const res = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ message, model }),
signal,
});
return res.body;
},
}),
[model],
);
// Stable reference — defined outside or memoized to avoid remounts
const HeaderActions = React.useMemo(
() =>
function ModelSelector() {
return (
<Select
value={model}
onChange={(e) => setModel(e.target.value)}
size="small"
>
<MenuItem value="gpt-4o">GPT-4o</MenuItem>
<MenuItem value="claude-3-5-sonnet">Claude 3.5 Sonnet</MenuItem>
</Select>
);
},
[model],
);
return (
<ChatBox
adapter={adapter}
slots={{ conversationHeaderActions: HeaderActions }}
/>
);
}
Implementation notes
ChatConversationHeaderActionsalready appliesmarginInlineStart: 'auto'so the selector floats to the right automatically.- Define the slot component outside the render function, or stabilize it with
React.useMemo, to avoid remounting the header on every render. - Use
size="small"onSelectto match the default header height.
See also
- Slot overrides for replacing deeper subcomponents
- Customization for the full slot key reference