import {
Channel,
ChannelHeader,
MessageInput,
MessageList,
Thread,
Window,
} from "stream-chat-react";
const App = () => (
<Channel>
<Window>
<ChannelHeader />
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
);This is beta documentation for Stream Chat React SDK v14. For the latest stable version, see the latest version (v13)
.
MessageInput
MessageInput provides the message-composer state, controls, and default UI for composing messages. It renders MessageInputContext for input UI components and uses MessageInputFlat by default.
Best Practices
- Keep
MessageInputunderChannelso composer state, permissions, and channel actions stay in sync. - Use
MessageInput Input={...}when only one composer instance should differ. - Use
WithComponentsfor shared composer subcomponent overrides such asAttachmentSelector,LinkPreviewList, orAudioRecorder. - Prefer composer middleware or
overrideSubmitHandlerfor send-pipeline logic, not for layout customization. - Use
messageComposer.threadIdto detect thread composition instead of relying on deprecatedisThreadInput.
Basic Usage
UI Customization
MessageInput does not render the composer UI itself. It renders the component provided through its Input prop, or the shared Input override from WithComponents, and that UI reads data from MessageInputContext.
Replace the whole input UI for one composer
import {
Channel,
ChannelHeader,
MessageInput,
MessageList,
TextareaComposer,
Thread,
Window,
} from "stream-chat-react";
const CustomInput = () => (
<div className="custom-input-shell">
<TextareaComposer />
</div>
);
const App = () => (
<Channel>
<Window>
<ChannelHeader />
<MessageList />
<MessageInput Input={CustomInput} />
</Window>
<Thread />
</Channel>
);Provide a shared input UI with WithComponents
import {
Channel,
ChannelHeader,
MessageInput,
MessageList,
Thread,
Window,
WithComponents,
} from "stream-chat-react";
const CustomInput = () => <div className="custom-input-shell">...</div>;
const App = () => (
<WithComponents overrides={{ Input: CustomInput }}>
<Channel>
<Window>
<ChannelHeader />
<MessageList />
<MessageInput />
</Window>
<Thread />
</Channel>
</WithComponents>
);Props
| Prop | Description | Type |
|---|---|---|
additionalTextareaProps | Additional props forwarded to TextareaComposer. | Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "defaultValue" | "style" | "disabled" | "value"> |
asyncMessagesMultiSendEnabled | When enabled, recorded voice messages stay in the composer preview stack instead of being sent immediately after recording completes. Defaults to false. | boolean |
audioRecordingConfig | Custom recording configuration for voice messages. | CustomAudioRecordingConfig |
audioRecordingEnabled | Enables voice-message recording UI. Defaults to false. | boolean |
emojiSearchIndex | Custom emoji search implementation used by autocomplete and emoji replacement. | ComponentContextValue["emojiSearchIndex"] |
focus | Focuses the textarea on mount. Defaults to false. | boolean |
hideSendButton | Hides the default send button inside the current input UI. Defaults to false. | boolean |
Input | Custom component that renders the whole composer UI. It should read data from MessageInputContext, MessageComposer, or other exported hooks instead of expecting injected props. Defaults to MessageInputFlat. | React.ComponentType<MessageInputProps> |
isThreadInput | Deprecated flag indicating the composer is used in a thread. Prefer messageComposer.threadId. | boolean |
maxRows | Maximum number of rows the default TextareaComposer can grow to. Defaults to 10. | number |
minRows | Minimum number of rows the default TextareaComposer starts with. | number |
overrideSubmitHandler | Overrides the default send flow for new messages. | (params: { cid: string; localMessage: LocalMessage; message: Message; sendOptions: SendMessageOptions; }) => Promise<void> | void |
parent | Parent message used when composing a thread reply. | LocalMessage |
shouldSubmit | Overrides the default submit shortcut. By default, Enter submits and Shift+Enter inserts a new line. | (event: React.KeyboardEvent<HTMLTextAreaElement>) => boolean |
Examples
Override the submit handler
import { MessageInput, type MessageInputProps } from "stream-chat-react";
const CustomMessageInput = () => {
const overrideSubmitHandler: MessageInputProps["overrideSubmitHandler"] =
async ({ cid, localMessage, message, sendOptions }) => {
// custom logic here
await sendMessageToBackend({ cid, localMessage, message, sendOptions });
};
return <MessageInput overrideSubmitHandler={overrideSubmitHandler} />;
};sendMessageToBackend in the example above is app-owned code.