# Message Input UI

Message input is used for composing and editing messages. It’s a primary interaction point in chat, so it’s worth getting right.

Message input is more than a text box + “send” button. It includes:

1. Updating the typing status
2. Uploading and previewing attachments
3. Displaying link previews
4. Auto-completing mentions, commands, emoji...

## Best Practices

- Compose input from pre-built components to preserve core behaviors.
- Keep `TextareaComposer` central for autocomplete and commands.
- Use `MessageInputContext` instead of passing handlers manually.
- Avoid rendering custom inputs outside `Channel`/`MessageInput`.
- Test attachments, previews, and typing updates together.

You can compose your Input UI component from pre-built components:

```tsx
import {
  AttachmentPreviewList,
  LinkPreviewList,
  QuotedMessagePreview,
  SimpleAttachmentSelector,
  useComponentContext,
  useMessageInputContext,
} from "stream-chat-react";

const SendButtonWithCooldown = () => {
  const { handleSubmit, cooldownRemaining, setCooldownRemaining } =
    useMessageInputContext();

  return cooldownRemaining ? (
    <CooldownTimer
      cooldownInterval={cooldownRemaining}
      setCooldownRemaining={setCooldownRemaining}
    />
  ) : (
    <SendButton sendMessage={handleSubmit} />
  );
};

const CustomMessageInput = () => (
  <div className="message-input">
    <div className={"left-container"}>
      <SimpleAttachmentSelector />
    </div>
    <div className={"central-container"}>
      <QuotedMessagePreview />
      <LinkPreviewList />
      <AttachmentPreviewList />
      <TextareaComposer />
    </div>
    <div className={"right-container"}>
      <SendButtonWithCooldown />
    </div>
  </div>
);
```

Don’t render your custom input directly. Instead pass it as a prop to
either [`Channel`](/chat/docs/sdk/react/components/core-components/channel/) or
[`MessageInput`](/chat/docs/sdk/react/components/message-input-components/message_input/) component. That way,
your input is wrapped with the necessary context providers, especially
the [`MessageInputContext`](/chat/docs/sdk/react/components/contexts/message_input_context/).

```tsx
import {
  Chat,
  Channel,
  ChannelHeader,
  ChannelList,
  MessageList,
  Thread,
  Window,
  MessageInput,
} from "stream-chat-react";
import { CustomMessageInput } from "./CustomMessageInput";

export const App = () => (
  <Chat client={chatClient}>
    <ChannelList filters={filters} sort={sort} options={options} />
    <Channel>
      <Window>
        <ChannelHeader />
        <MessageList />
        <MessageInput Input={CustomMessageInput} />
      </Window>
      <Thread />
    </Channel>
  </Chat>
);
```


---

This page was last updated at 2026-03-06T17:06:45.860Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/guides/theming/input_ui/](https://getstream.io/chat/docs/sdk/react/guides/theming/input_ui/).