--- id: message_input sidebar_position: 6 title: MessageInput --- A Widget Dealing With Everything Related To Sending A Message ### Background In Stream Chat, we can send messages in a channel. However, sending a message isn't as simple as adding a `TextField` and logic for sending a message. It involves additional processes like addition of media, quoting a messages, adding a custom command like a GIF board, and much more. Moreover, most apps also need to customize the input to match their theme, overall color and structure pattern, etc. To do this, we created a `MessageInput` widget which abstracts all expected functionality a modern input needs - and allows you to use it out of the box. ### Basic Example A `StreamChannel` is required above the widget tree in which the `MessageInput` is rendered since the channel is where the messages sent actually go. Let's look at a common example of how we could use the `MessageInput`: ```dart class ChannelPage extends StatelessWidget { const ChannelPage({ Key key, }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: ChannelHeader(), body: Column( children: [ Expanded( child: MessageListView( threadBuilder: (_, parentMessage) { return ThreadPage( parent: parentMessage, ); }, ), ), MessageInput(), ], ), ); } } ``` It is common to put this widget in the same page of a [MessageListView] as the bottom widget. ### Quoting A Message The quoting functionality allows us to 'reply' to a specific message without creating a thread out of it. It adds the other message as context when sending a message and also displays it above the sent message. To quote a message, we provide a `quotedMessage` to the `MessageInput`. ```dart Message? message; // ... MessageInput( quotedMessage: message, ), ``` This will add the message given above the message about to be sent. While you can implement your own functionality to select which message to reply to, the `MessageListView` widget helps in this case since it has an inbuilt `onMessageSwiped` callback which we can use. ```dart class ChannelPage extends StatefulWidget { @override _ChannelPageState createState() => _ChannelPageState(); } class _ChannelPageState extends State { Message? quotedMessage; @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Expanded( child: MessageListView( // ... onMessageSwiped: (message) { setState(() { quotedMessage = message; }); }, ), ), MessageInput( quotedMessage: _quotedMessage, onQuotedMessageCleared: () { setState(() => _quotedMessage = null); }, ), ], ), ); } } ```