# Mentions

## What users get

Typing `@` in the composer suggests people and groups to mention. The sent message highlights each mention, and the server notifies the people it names.

- **Suggestions.** `@` opens a list of channel members, `@channel`, `@here`, roles and user groups, narrowed as the user types. The local member search ignores common accents such as é and ü by default, so "rene" finds "René".
- **Inserting.** Picking a suggestion inserts it into the text, for example `@Ben`. Deleting that text removes the mention.
- **Highlighting.** Mentions in sent messages are styled, and can be clicked or hovered.

![Typing @rene suggests René](https://getstream.io/docs-assets/images/af97025c32c7.png)

There are five kinds of mention. The kinds other than `user` need a capability in the channel:

| Kind         | Typed as   | Notifies                | Capability       | Permission in the dashboard |
| ------------ | ---------- | ----------------------- | ---------------- | --------------------------- |
| `user`       | `@<name>`  | one user                | none             | none                        |
| `channel`    | `@channel` | everyone in the channel | `notify-channel` | `NotifyChannel`             |
| `here`       | `@here`    | members who are online  | `notify-here`    | `NotifyHere`                |
| `role`       | `@<role>`  | users with that role    | `notify-role`    | `NotifyRole`                |
| `user_group` | `@<group>` | members of a user group | `notify-group`   | `NotifyGroup`               |

The message field each kind is sent in is listed in [Kinds of mentions](https://getstream.io/chat/docs/sdk/react/state/writing-messages/mentions/#kinds-of-mentions). A received message lists its user groups in `mentioned_groups`.

## How it works across the layers

### State: the text composer

The user types "Thanks @be" in "Design":

1. The text composer runs its middleware on every change. The mentions middleware finds the `@be` before the cursor and asks `MentionsSearchSource` for suggestions.
2. The search source collects users, `@channel` and `@here`, roles and user groups that match "be". It offers only the kinds the user has the capability for. [Where the suggestions come from](https://getstream.io/chat/docs/sdk/react/state/writing-messages/mentions/#where-the-suggestions-come-from) explains each search.
3. The suggestions land in the text composer's state as `suggestions`, and the UI lists them.
4. The user picks Ben. The middleware replaces `@be` with `@Ben` and adds Ben to the text composer's `mentions`.
5. When they send, the composer sends each mention that is still in the text with the message.

The middleware and the search source are explained on [Mentions](https://getstream.io/chat/docs/sdk/react/state/writing-messages/mentions/).

### UI: suggestions and highlighting

The input, `TextareaComposer`, renders the suggestion list while the text composer has suggestions:

- `AutocompleteSuggestionList`, by default `SuggestionList`, lists them and handles the keyboard.
- Each row is an `AutocompleteSuggestionItem`. For `@`, the row renders `MentionItem`, which picks `UserItem`, `BroadcastMentionItem` (`@channel` and `@here`), `RoleItem` or `UserGroupItem`.

In the message list, the message text is rendered by `renderText`, which turns each mention into a `Mention` element:

```html
<span
  class="str-chat__message-mention"
  data-mention-type="user | channel | here | role | user_group"
  data-mention-id="<the mentioned entity's id>"
  data-user-id="<the user's id, for user mentions only>"
>
  @Ben
</span>
```

`<MessageList/>` takes `onMentionsClick` and `onMentionsHover`. They run when the user clicks or hovers the text of a message that has mentions. With `onMentionsClick`, each `@name` in the text gets `cursor: pointer`, and the message text can be reached with Tab: pressing Enter or Space on it calls the handler, as a click does. Without it, mentions are highlighted but not clickable. [Reacting to clicks and hovers](#reacting-to-clicks-and-hovers) shows a handler. See [The input](https://getstream.io/chat/docs/sdk/react/ui/components/message-composer-ui/#the-input) for the composer side.

## Turning it on or off

User mentions are always available. Grant the capabilities in the table under [What users get](#what-users-get) in the [Stream Dashboard](https://getstream.io/signin/?product=chat) under **Chat Messaging → Roles & Permissions**: pick the role (for example `channel_member`) and the channel type (for example `messaging`), then turn on the permissions. Until the user has a capability, that kind doesn't appear in the suggestions.

Two kinds also need data on the server:

- **Roles** are the roles defined on the same **Roles & Permissions** page.
- **User groups** are named sets of users, mentioned as one with `@<group name>`. They don't depend on channel membership: a group can be mentioned in any channel where group mentions are allowed. Create and manage them with a server-side SDK; see the [User Groups API reference](https://getstream.io/chat/docs/javascript/user-groups/).

## Customizing

### Changing the search

To change what is searched, for example to suggest every user of the app or to change the page size, give the mentions middleware a `MentionsSearchSource` of your own; see [Customizing mention search](https://getstream.io/chat/docs/sdk/react/state/writing-messages/mentions/#customizing-mention-search) for the options and a sample.

Its `transliterate` option also lets names written in other scripts match what the user types. Pass a function that returns the text in Latin script, such as the default export of `@sindresorhus/transliterate`, and typing "@ana" suggests "Анатолий". It applies only to names compared locally; queries to the server aren't transliterated.

![Typing @ana suggests Анатолий](https://getstream.io/docs-assets/images/42c316740815.png)

The search source is replaced in a `messageComposer` setup function. There is one setup function per kind, so do all composer setup in one; see [Setup functions](https://getstream.io/chat/docs/sdk/react/state/state-and-entities/configuration/#setup-functions).

### Replacing a suggestion row

Pass your own row components to `MentionItem`, and give the list the new `@` row through `SuggestionList`'s `suggestionItemComponents`:

```tsx
import type { MentionSuggestion } from "stream-chat";
import type {
  SuggestionListItemComponentProps,
  SuggestionListProps,
  UserItemProps,
} from "stream-chat-react";
import {
  defaultComponents,
  MentionItem,
  SuggestionList,
  UserItem,
  WithComponents,
} from "stream-chat-react";

const UserRow = (props: UserItemProps) => (
  <UserItem {...props} className="user-row" />
);

const MentionRow = (props: SuggestionListItemComponentProps) => (
  <MentionItem
    {...props}
    entity={props.entity as MentionSuggestion}
    UserItem={UserRow}
  />
);

const Suggestions = (props: SuggestionListProps) => (
  <SuggestionList
    {...props}
    suggestionItemComponents={{ ...defaultComponents, "@": MentionRow }}
  />
);

export const App = () => (
  <WithComponents overrides={{ AutocompleteSuggestionList: Suggestions }}>
    {/* the rest of the app */}
  </WithComponents>
);
```

`MentionItem` also takes `BroadcastMentionItem`, `RoleItem` and `UserGroupItem`, and `SpecialMentionItem` for any other kind. The [Custom suggestions](https://getstream.io/chat/docs/sdk/react/ui-cookbooks/composer/custom-suggestions/) recipe builds complete rows.

### Styling mentions

Each mention has `data-mention-type`, so CSS can style the kinds differently:

```css
.str-chat__message-mention[data-mention-type="channel"],
.str-chat__message-mention[data-mention-type="here"] {
  color: var(--str-chat__accent-error);
}
```

To render mentions with your own markup, for example as links to profiles, pass a `mention` component to `renderText`; see [Custom element rendering](https://getstream.io/chat/docs/sdk/react/component-reference/message/rendertext-function/#custom-element-rendering).

### Reacting to clicks and hovers

To do something when the user clicks a mention, such as opening the user's profile, pass `onMentionsClick` to `<MessageList/>`, `<VirtualizedMessageList/>` or `<Message/>`. `onMentionsHover` does the same for hovers. Both are called with `(event, message)`.

The handler doesn't say which mention was clicked: it runs for a click anywhere in the message text. Find the mention from the clicked element:

1. Look up the nearest `.str-chat__message-mention` from `event.target`. Without one, the click wasn't on a mention.
2. Read the mention from the element's `data-mention-id` and `data-mention-type`. A user mention also has `data-user-id`.

Enter or Space on the message text also calls `onMentionsClick`. Its target is the whole text, so the handler finds no mention and does nothing:

```tsx
import type { CustomMentionHandler } from "stream-chat-react";
import { MessageList } from "stream-chat-react";

const handleMentionClick: CustomMentionHandler = (event, message) => {
  const target = event.target as HTMLElement;
  const mention = target.closest<HTMLElement>(".str-chat__message-mention");
  if (!mention) return;

  const { mentionId, mentionType } = mention.dataset;

  if (mentionType === "user") {
    const user = message.mentioned_users?.find(({ id }) => id === mentionId);
    console.log("Open the profile of", user?.name ?? mentionId);
  } else {
    console.log("Clicked a", mentionType, "mention");
  }
};

export const MessageListWithMentionClicks = () => (
  <MessageList onMentionsClick={handleMentionClick} />
);
```

In a thread, the parent message gets the list's handlers too.

To read a context from inside a mention, such as `MessageContext`, render a custom `mention` component through `renderText`.

## Reference

- State: [Mentions](https://getstream.io/chat/docs/sdk/react/state/writing-messages/mentions/), [Suggestions](https://getstream.io/chat/docs/sdk/react/state/writing-messages/suggestions/), [Composer middleware](https://getstream.io/chat/docs/sdk/react/state/writing-messages/composer-middleware/) and the [MessageComposer API](https://getstream.io/chat/docs/sdk/react/reference/state/messagecomposer-api/).
- UI: [Message composer UI](https://getstream.io/chat/docs/sdk/react/ui/components/message-composer-ui/#the-input) and [Message UI](https://getstream.io/chat/docs/sdk/react/ui/components/message-ui/).
- Props: [Input UI](https://getstream.io/chat/docs/sdk/react/component-reference/message-composer/input-ui/), [renderText function](https://getstream.io/chat/docs/sdk/react/component-reference/message/rendertext-function/) and [MessageList](https://getstream.io/chat/docs/sdk/react/component-reference/message-list/messagelist/).
- Hooks: [Message hooks](https://getstream.io/chat/docs/sdk/react/reference/hooks/message-hooks/).

---

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