# Message Reactions

## Reactions Overview

The SwiftUI chat SDK provides a default view that's displayed as an overlay of the message. When you long press on a message, the message reactions overlay is shown. By default, it shows a blurred background and a possibility to react to a message or remove a reaction. Additionally, the reactions overlay has a "message actions" slot, which allows you to perform actions on the message. Both the displayed reactions on a message and the reactions overlay can be replaced by your own views.

When reactions are added to a message, a view displaying the added reactions is shown above the message. When this view is tapped or long-pressed, a new overlay view displaying the list of people who reacted to a message is presented. That view can also be swapped with your own implementation.

## Customizing the Message Reactions View

In the SwiftUI SDK, reactions are emoji-based. The `availableMessagesReactionEmojis` property on `Appearance.Images` controls which reactions are available in the picker and how they render on messages. It maps `MessageReactionType` keys to emoji strings:

```swift
var images = Appearance.Images()
images.availableMessagesReactionEmojis = [
    "love": "❤️",
    "like": "👍",
    "haha": "😂",
    "wow": "😮",
    "sad": "😢"
]
var appearance = Appearance()
appearance.images = images

let streamChat = StreamChat(chatClient: chatClient, appearance: appearance)
```

The "More Reactions" picker (shown when tapping the `+` button in the reactions overlay) uses a separate `availableEmojis` property on `Appearance.Images`, which contains the full grid of emojis users can choose from.

You can also change the colors of the reactions by modifying the following properties on `ColorPalette`:

- `reactionBackground` — the background color of reaction bubbles.
- `reactionBorder` — the border color of reaction bubbles.
- `reactionText` — the text and tint color of reaction icons.

The selected state of a reaction (when the current user has reacted) uses `backgroundUtilitySelected`.

Here's an example of how to change these values:

```swift
var colors = Appearance.ColorPalette()
colors.reactionBackground = UIColor.systemGray6
colors.reactionBorder = UIColor.systemGray4
colors.reactionText = UIColor.label

var appearance = Appearance()
appearance.colorPalette = colors

let streamChat = StreamChat(chatClient: chatClient, appearance: appearance)
```

By default, the reactions are sorted by their raw value in an alphabetical order. You can change this logic by adding your own implementation of the `sortReactions` closure in the `Utils` class.

Here's an example how to achieve this:

```swift
let customReactionSort: (MessageReactionType, MessageReactionType) -> Bool = { lhs, rhs in
    // Your custom sorting logic here
    lhs.rawValue < rhs.rawValue
}
let utils = Utils(sortReactions: customReactionSort)
streamChat = StreamChat(chatClient: chatClient, utils: utils)
```

## Changing the Message Reactions View

Alternatively, you can completely swap the `ReactionsContainer` view with your own implementation. In order to do that, you need to implement the `makeMessageReactionView` method from the `ViewFactory`:

```swift
public func makeMessageReactionView(
    options: MessageReactionViewOptions
) -> some View {
    CustomReactionsContainer(message: options.message)
}
```

The `MessageReactionViewOptions` provides:

- `message` – the `ChatMessage` whose reactions are displayed.
- `onTapGesture` – callback when the reactions view is tapped.
- `onLongPressGesture` – callback when the reactions view is long-pressed.

## Customizing the Reactions Overlay View

The reactions overlay view (shown on long press of a message) also provides access to the message actions. To replace or extend the default message actions, configure them via `messageListConfig`:

```swift
let utils = Utils(
    messageListConfig: MessageListConfig(
        supportedMessageActions: { options in
            MessageAction.defaultActions(for: options)
        }
    )
)
let streamChat = StreamChat(chatClient: chatClient, utils: utils)
```

Alternatively, you can swap the whole `MessageActionsView` with your own implementation, by implementing the `makeMessageActionsView` method in the `ViewFactory`:

```swift
public func makeMessageActionsView(
    options: MessageActionsViewOptions
) -> some View {
    let messageActions = InjectedValues[\.utils].messageListConfig.supportedMessageActions(
        SupportedMessageActionsOptions(
            message: options.message,
            channel: options.channel,
            onFinish: options.onFinish,
            onError: options.onError
        )
    )
    return MessageActionsView(messageActions: messageActions)
}
```

The `MessageActionsViewOptions` provides:

- `message` – the message for which actions are shown.
- `channel` – the channel where the message lives.
- `onFinish` – callback when an action finishes successfully.
- `onError` – callback when an action fails.

As mentioned at the beginning, when the reactions are tapped or long-pressed, a view with the list of users who reacted to the message is displayed. In order to change this view with your own implementation, you will need to implement the `makeReactionsDetailView` in the `ViewFactory`.

```swift
func makeReactionsDetailView(options: ReactionsDetailViewOptions) -> some View {
    ReactionsDetailView(message: options.message)
}
```

The `ReactionsDetailViewOptions` provides:

- `message` – the message whose reaction authors to display.

The background of the reactions overlay is a blurred snapshot of the current channel view, handled internally by the `ReactionsOverlayView`.

You can customize the snapshot generation logic by providing your own implementation of the `SnapshotCreator` protocol, which has one method `func makeSnapshot(for view: AnyView) -> UIImage`. The `view` parameter is the SwiftUI view which invokes the reactions overlay presentation (the `ChatChannelView`), while the generated `UIImage` is used as the blurred background of the overlay.

To inject a custom snapshot creator, pass it to the `Utils` class:

```swift
let snapshotCreator = CustomSnapshotCreator()
let utils = Utils(snapshotCreator: snapshotCreator)
let streamChat = StreamChat(chatClient: chatClient, utils: utils)
```

Finally, you can swap the whole `ReactionsOverlayView` with your own implementation. In order to do this, you need to implement the `makeReactionsOverlayView` method in the `ViewFactory`. The current snapshot of the message list is provided to you, in case you want to blur it or apply any other effects.

```swift
public func makeReactionsOverlayView(
    options: ReactionsOverlayViewOptions
) -> some View {
    ReactionsOverlayView(
        factory: self,
        channel: options.channel,
        currentSnapshot: options.currentSnapshot,
        messageDisplayInfo: options.messageDisplayInfo,
        onBackgroundTap: options.onBackgroundTap,
        onActionExecuted: options.onActionExecuted
    )
}
```

The `ReactionsOverlayViewOptions` provides:

- `channel` – the channel where the message lives.
- `currentSnapshot` – the current snapshot of the message list.
- `messageDisplayInfo` – display information about the message (position, size, etc.).
- `onBackgroundTap` – callback when the background is tapped to dismiss.
- `onActionExecuted` – callback when a message action is executed.


---

This page was last updated at 2026-05-13T13:38:43.463Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/ios/swiftui/message-components/message-reactions/](https://getstream.io/chat/docs/sdk/ios/swiftui/message-components/message-reactions/).