# StreamMessageWidget

A Widget For Displaying Messages And Attachments

Find the pub.dev documentation [here](https://pub.dev/documentation/stream_chat_flutter/latest/stream_chat_flutter/StreamMessageWidget-class.html)

### Background

`StreamMessageWidget` is a thin shell widget that renders a single message, including its attachments, reactions, sender avatar, timestamp, and other metadata.

In v10 (design-refresh), the widget was refactored from a monolithic ~50-parameter component into a clean architecture:

- **`StreamMessageWidget`** — thin shell, resolves the `StreamComponentFactory` and delegates rendering
- **`StreamMessageWidgetProps`** — plain data class holding all configuration, supports `copyWith()`
- **`DefaultStreamMessage`** — default rendering implementation, composes the sub-components below
- **`StreamMessageContent`** — bubble, attachments, text, reactions, thread replies
- **`StreamMessageFooter`** — username, timestamp, sending status, edited indicator
- **`StreamMessageLeading`** — author avatar
- **`StreamMessageReactions`** — clustered reaction chips around the bubble
- **`StreamMessageText`** — markdown-rendered message text

### Basic Example

The `StreamMessageWidget` is primarily used inside `StreamMessageListView`. Use the `messageBuilder` callback to customize individual messages. The callback now receives `StreamMessageWidgetProps` (raw configuration data) instead of a pre-built widget:

```dart
class ChannelPage extends StatelessWidget {
  const ChannelPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamMessageListView(
        messageBuilder: (context, message, defaultProps) {
          // Build the default widget (goes through component factory)
          return StreamMessageWidget.fromProps(props: defaultProps);
        },
      ),
    );
  }
}
```

### Customizing via `copyWith`

Use `StreamMessageWidgetProps.copyWith()` to customize specific properties:

```dart
StreamMessageListView(
  messageBuilder: (context, message, defaultProps) {
    return StreamMessageWidget.fromProps(
      props: defaultProps.copyWith(
        actionsBuilder: (context, defaultActions) => [
          ...defaultActions,
          StreamContextMenuAction(
            leading: const Icon(Icons.star),
            label: const Text('Favourite'),
            onTap: () => _favourite(message),
          ),
        ],
      ),
    );
  },
)
```

### New Callback Signatures

Several callbacks have been renamed or changed signature:

| Old                                          | New                                                    |
| -------------------------------------------- | ------------------------------------------------------ |
| `onLinkTap: void Function(String url)`       | `onMessageLinkTap: void Function(Message, String url)` |
| `onMentionTap: void Function(User)`          | `onUserMentionTap: void Function(User)`                |
| `onQuotedMessageTap: void Function(String?)` | `onQuotedMessageTap: void Function(Message)`           |

```dart
StreamMessageListView(
  onMessageLinkTap: (message, url) => launchUrl(Uri.parse(url)),
  onUserMentionTap: (user) => showProfile(user),
  onQuotedMessageTap: (quotedMessage) => scrollToMessage(quotedMessage.id),
)
```

### New List-Level Callbacks

These callbacks can now be set at the list level and are forwarded to all messages:

| Parameter            | Type                              |
| -------------------- | --------------------------------- |
| `onEditMessageTap`   | `void Function(Message)?`         |
| `onReplyTap`         | `void Function(Message)?`         |
| `onUserAvatarTap`    | `void Function(User)?`            |
| `onReactionsTap`     | `void Function(Message)?`         |
| `onQuotedMessageTap` | `void Function(Message)?`         |
| `onMessageLinkTap`   | `void Function(Message, String)?` |
| `onUserMentionTap`   | `void Function(User)?`            |

### Building Custom Attachments

Register custom attachment builders globally via `StreamChatConfigurationData`:

```dart
StreamChat(
  client: client,
  streamChatConfigData: StreamChatConfigurationData(
    attachmentBuilders: [
      LocationAttachmentBuilder(),
      ...defaultAttachmentBuilders,
    ],
  ),
  child: ...,
)
```

You can also override attachment builders per-message via `StreamMessageWidgetProps.attachmentBuilders`.

### Swipeable Messages Example

```dart
StreamMessageListView(
  messageBuilder: (context, message, defaultProps) {
    final defaultWidget = StreamMessageWidget.fromProps(props: defaultProps);

    if (message.isDeleted || message.state.isFailed) return defaultWidget;

    final alignment = StreamMessagePlacement.alignmentDirectionalOf(context);
    final isEnd = alignment == AlignmentDirectional.centerEnd;

    return Swipeable(
      key: ValueKey(message.id),
      direction: isEnd ? SwipeDirection.endToStart : SwipeDirection.startToEnd,
      swipeThreshold: 0.2,
      onSwiped: (_) => onReply(message),
      child: defaultWidget,
    );
  },
)
```

### Theming

Theme is now resolved automatically from context — no `messageTheme` parameter needed:

```dart
// Old (v9 and earlier)
StreamMessageWidget(
  message: message,
  messageTheme: isMyMessage
      ? streamTheme.ownMessageTheme
      : streamTheme.otherMessageTheme,
)

// New
StreamMessageWidget(message: message)
```

Use `StreamMessageItemThemeData` to control visibility and styling via the theme system:

```dart
StreamChatThemeData(
  // Configure per-message item theming...
)
```

### Removed Parameters

Many parameters that existed on `StreamMessageWidget` have been removed. Here is the migration path:

| Removed Parameter                             | Migration Path                                     |
| --------------------------------------------- | -------------------------------------------------- |
| `showReactions`                               | `StreamMessageItemThemeData` visibility            |
| `showDeleteMessage` / `showEditMessage`       | Channel permissions                                |
| `showUsername` / `showTimestamp`              | `StreamMessageItemThemeData.footerVisibility`      |
| `showUserAvatar`                              | `StreamMessageItemThemeData.leadingVisibility`     |
| `userAvatarBuilder`                           | Component factory (replace `DefaultStreamMessage`) |
| `textBuilder`                                 | Component factory (replace `StreamMessageContent`) |
| `customActions`                               | `actionsBuilder` on `StreamMessageWidgetProps`     |
| `onCustomActionTap`                           | `onTap` per `StreamContextMenuAction`              |
| `reverse`                                     | Determined by `StreamMessagePlacement` context     |
| `messageTheme`                                | Resolved from context automatically                |
| `shape`, `borderSide`, `borderRadiusGeometry` | `StreamMessageBubble` theming                      |
| `copyWith()` on `StreamMessageWidget`         | `StreamMessageWidgetProps.copyWith()`              |


---

This page was last updated at 2026-06-03T06:36:03.154Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/flutter/v10/stream-chat-flutter/message-list/stream-message-widget/](https://getstream.io/chat/docs/sdk/flutter/v10/stream-chat-flutter/message-list/stream-message-widget/).