<Chat client={client}>
<ChannelList />
<Channel>
<MessageList />
<MessageInput />
</Channel>
</Chat>MessageInput
MessageInput wraps the logic, state, and UI for composing messages. It provides MessageInputContext to its children, which all input UI components consume.
Best Practices
- Keep
MessageInputunderChannelso context and actions are available. - Use custom
Inputonly when you need layout changes, not minor styling. - Prefer composer middleware over
overrideSubmitHandlerfor message logic. - Avoid deprecated
isThreadInput; rely onmessageComposer.threadId. - Keep textarea row limits aligned with your UX guidelines.
Basic Usage
MessageInput must be rendered under Channel. It has no required props and builds MessageInputContext using internal hooks.
If you don’t pass a custom Input, MessageInputFlat is used by default.
UI Customization
MessageInput doesn’t render UI itself; customization is handled by the Input UI component passed via the Input prop on Channel or MessageInput.
Props
additionalTextareaProps
Additional props to be consumed by the underlying TextareaComposer component.
type additionalTextareaProps = Omit<
React.TextareaHTMLAttributes<HTMLTextAreaElement>,
"defaultValue" | "style" | "disabled" | "value"
>;clearEditingState
Function to clear the editing state while editing a message.
| Type |
|---|
| () => void |
focus
If true, focuses the text input on component mount.
| Type | Default |
|---|---|
| boolean | false |
hideSendButton
Allows to hide MessageInput's send button. Used by MessageSimple to hide the send button in EditMessageForm.
| Type | Default |
|---|---|
| boolean | false |
Input
Custom UI component handling how the message input is rendered.
| Type | Default |
|---|---|
| component | MessageInputFlat |
isThreadInput
Signals that the MessageInput is rendered in a message thread (Thread component).
This prop is deprecated. Use messageComposer.threadId to determine whether a thread reply is being composed.
| Type |
|---|
| boolean |
maxRows
Max number of rows the underlying textarea component is allowed to grow.
| Type | Default |
|---|---|
| number | 10 |
minRows
Min number of rows the underlying textarea will start with.
| Type | Default |
|---|---|
| number | 1 |
overrideSubmitHandler
Function to override the default submit handler. This isn’t intended for message composition; use custom composition middleware instead (guide here: /chat/docs/sdk/react/components/message-input-components/message-composer-middleware#message-composer-middleware-overview).
type overrideSubmitHandler = (params: {
cid: string; // target channel CID
localMessage: LocalMessage; // object representing the local message data used for UI update
message: Message; // object representing the payload sent to the server for message creation / update
sendOptions: SendMessageOptions;
}) => Promise<void> | void;import { MessageInput } from "stream-chat-react";
import type { MessageInputProps } from "stream-chat-react";
const CustomMessageInput = (props: MessageInputProps) => {
const submitHandler: MessageInputProps["overrideSubmitHandler"] = useCallback(
async (params: {
cid: string;
localMessage: LocalMessage;
message: Message;
sendOptions: SendMessageOptions;
}) => {
// custom logic goes here
await sendMessage({ localMessage, message, options: sendOptions });
},
[sendMessage],
);
return (
<StreamMessageInput {...props} overrideSubmitHandler={submitHandler} />
);
};parent
When replying in a thread, the parent message object.
| Type |
|---|
| object |
shouldSubmit
Currently, Enter is the default submission key and Shift+Enter is the default combination for the new line.
If specified, this function overrides the default behavior specified previously.
| Type |
|---|
| (event: KeyboardEvent) => boolean |
Migration from versions older than 9.0.0
Property keycodeSubmitKeys has been replaced by shouldSubmit and thus is no longer supported. If you had custom key codes specified like so:
keyCodeSubmitKeys={[[16,13], [57], [48]]} // submission keys are Shift+Enter, 9, and 0then that would newly translate to:
const shouldSubmit = (event) =>
(event.key === 'Enter' && event.shiftKey) || event.key === '9' || event.key === '0';
...
shouldSubmit={shouldSubmit}