# Mentions

Stream Chat lets a sender notify more than one user at a time. Beyond direct user mentions (`@<user>`), a message can target everyone in a channel (`@channel`), only the members currently online (`@here`), everyone holding a given role (`@<role>`), or a named user group (`@<group>`).

The SDK exposes each of these as a `Mention` subtype, plumbs them through the message composer and the message list, and lets you control which kinds are available per channel via channel capabilities.

## Mention kinds

`Mention` is an interface with five built-in implementations:

| Subtype                | Token           | Notifies                                                           |
| ---------------------- | --------------- | ------------------------------------------------------------------ |
| `Mention.User(user)`   | `@<user name>`  | A single user                                                      |
| `Mention.Channel`      | `@channel`      | Every member of the channel                                        |
| `Mention.Here`         | `@here`         | Online members only                                                |
| `Mention.Role(role)`   | `@<role>`       | Every user with that role (up to 10 roles per message)             |
| `Mention.Group(group)` | `@<group name>` | Every member of the named user group (up to 10 groups per message) |

Each kind maps to a server-side channel capability. For the four `notify-*` kinds, the composer skips that kind in its suggestions when the channel does not return the capability, and trying to send the mention is rejected by the server. User mentions behave differently: the composer always shows user suggestions regardless of `create-mention`, and the capability is only enforced on send under Permissions V2 (on Permissions V1, regular members lack `create-mention` yet user mentions still work).

| Capability       | Constant                             | Required for   |
| ---------------- | ------------------------------------ | -------------- |
| `create-mention` | `ChannelCapabilities.CREATE_MENTION` | User mentions  |
| `notify-channel` | `ChannelCapabilities.NOTIFY_CHANNEL` | `@channel`     |
| `notify-here`    | `ChannelCapabilities.NOTIFY_HERE`    | `@here`        |
| `notify-role`    | `ChannelCapabilities.NOTIFY_ROLE`    | Role mentions  |
| `notify-group`   | `ChannelCapabilities.NOTIFY_GROUP`   | Group mentions |

Whether a message actually triggers a push for any given recipient depends on that user's push preferences. See [Push Preferences](/chat/docs/android/push-preferences/) for the full reference.


## Sending mentions from the composer

`MessageComposer` reads the active channel's capabilities and surfaces the matching kinds in the suggestion popup automatically. Typing `@` shows users members matching the query plus any of `@channel`, `@here`, matching roles, and matching groups that the channel allows. Picking an item inserts the token and remembers the selection; on send, the composer populates the right fields on the outgoing `Message`.

The only thing to wire up is the selection callback, which receives a `Mention`:

```kotlin
MessageComposer(
    viewModel = composerViewModel,
    onMentionSelected = { mention ->
        composerViewModel.selectMention(mention)
    },
)
```

`viewModel.selectMention(mention)` is the default, so omitting `onMentionSelected` works for most apps. Override it when you want to react to the selection (analytics, custom autocomplete behaviour) on top of inserting the token.

## Building a message by hand

When sending a message without going through the built-in composer, set the mention fields directly on `Message`:

```kotlin
val message = Message(
    cid = cid,
    text = "Heads up @channel, the backup is failing",
    mentionedChannel = true,
)
chatClient.channel(cid).sendMessage(message).enqueue()
```

The full set of fields is:

| Field               | Type              | Meaning                  |
| ------------------- | ----------------- | ------------------------ |
| `mentionedUsersIds` | `List<String>`    | User IDs to ping by name |
| `mentionedChannel`  | `Boolean`         | `@channel` is set        |
| `mentionedHere`     | `Boolean`         | `@here` is set           |
| `mentionedRoles`    | `List<String>`    | Role names to ping       |
| `mentionedGroups`   | `List<UserGroup>` | User groups to ping      |

Server limits: 100 user IDs (25 on update), 10 roles, 10 groups.


## Rendering and click handling

Incoming messages style and linkify every mention token automatically when the matching field on `Message` is set.

`MessageItem`, `MessageContainer`, `MessageContent`, and `MessageText` accept an `onMentionClick: (Mention) -> Unit` callback that fires for every mention kind. When using the higher-level `MessageList`, wire the handler by overriding `ChatComponentFactory.MessageItem`:

```kotlin
class MyComponentFactory : ChatComponentFactory {
    @Composable
    override fun MessageItem(params: MessageItemParams) {
        super.MessageItem(
            params = params.copy(
                onMentionClick = { mention ->
                    when (mention) {
                        is Mention.User -> openProfile(mention.user.id)
                        is Mention.Group -> openGroupInfo(mention.group.id)
                        is Mention.Role -> openRoleInfo(mention.role)
                        Mention.Channel, Mention.Here -> Unit
                    }
                },
            ),
        )
    }
}

ChatTheme(componentFactory = MyComponentFactory()) {
    // ...
}
```

## Customizing the suggestion popup

Override the suggestion row via `ChatComponentFactory.MessageComposerSuggestionItem`. The row gets a `Mention` and a selection callback; the leading, center, and trailing slots can each be overridden separately.

```kotlin
class MyComponentFactory : ChatComponentFactory {
    @Composable
    override fun MessageComposerSuggestionItemLeadingContent(
        params: MessageComposerSuggestionItemLeadingContentParams,
    ) {
        val icon = when (params.mention) {
            Mention.Channel -> R.drawable.ic_megaphone
            Mention.Here -> R.drawable.ic_users
            is Mention.Role -> R.drawable.ic_role
            is Mention.Group -> R.drawable.ic_users
            is Mention.User -> R.drawable.ic_person
            else -> return
        }
        Icon(painter = painterResource(icon), contentDescription = null)
    }
}

ChatTheme(componentFactory = MyComponentFactory()) {
    // ...
}
```

## Styling mentions in rendered text

Mention styling goes through `MessageTextFormatter`. The default formatter accepts a `mentionColor` lambda for a single colour applied to every mention, or a `builder` lambda for full control over the `AnnotatedString`.

```kotlin
ChatTheme(
    messageTextFormatter = MessageTextFormatter.defaultFormatter(
        autoTranslationEnabled = false,
        mentionColor = { isMine -> if (isMine) Color.White else Color(0xFF005FFF) },
    ),
) {
    // ...
}
```

For per-kind styling, pass a `builder` that walks the annotations and applies a `SpanStyle` keyed off the mention type tag.


---

This page was last updated at 2026-07-01T15:44:14.585Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/android/compose/mentions/](https://getstream.io/chat/docs/sdk/android/compose/mentions/).