# Mention
URL: /docs/ui/mention
Let users @-mention tools in the composer with a keyboard-navigable popover picker and inline chips.
Getting Started \[#getting-started]
Add `composer-mention` \[#add-composer-mention]
This adds a `/components/assistant-ui/composer-mention.tsx` file with `ComposerMentionPopover`, `ComposerMentionRoot`, and `DirectiveText`.
Wrap the Composer \[#wrap-the-composer]
Wrap your composer with `ComposerMentionPopover.Root` and add `` inside:
```tsx title="components/assistant-ui/thread.tsx" {1,7,10}
import { ComposerMentionPopover } from "@/components/assistant-ui/composer-mention";
const Composer = () => {
return (
);
};
```
The popover automatically shows registered tools when the user types `@`.
Render Mentions in User Messages \[#render-mentions-in-user-messages]
Use `DirectiveText` as the `Text` component for **user messages** so mention directives render as inline chips instead of raw `:tool[label]` syntax:
```tsx title="components/assistant-ui/thread.tsx" {1,8}
import { DirectiveText } from "@/components/assistant-ui/composer-mention";
const UserMessage = () => {
return (
);
};
```
`DirectiveText` renders plain text with mention chips. For assistant messages
that contain markdown, keep using your markdown renderer (e.g. `MarkdownText`).
With Lexical Rich Editor \[#with-lexical-rich-editor]
For inline mention chips in the composer (not just the popover), use `LexicalComposerInput` from `@assistant-ui/react-lexical`:
```bash
npm install @assistant-ui/react-lexical lexical @lexical/react
```
Replace `ComposerPrimitive.Input` with `LexicalComposerInput`:
```tsx title="components/assistant-ui/thread.tsx" {1,8}
import { LexicalComposerInput } from "@assistant-ui/react-lexical";
const Composer = () => {
return (
);
};
```
`LexicalComposerInput` auto-wires to `MentionContext` — no extra props needed. Selected mentions appear as inline chips that are treated as atomic units (select, delete, undo as a whole).
Custom Formatter \[#custom-formatter]
The default directive format is `:type[label]{name=id}`. To use a custom format, pass a `formatter` to both the mention root and the message renderer:
```tsx
import { ComposerMentionPopover } from "@/components/assistant-ui/composer-mention";
import { createDirectiveText } from "@/components/assistant-ui/composer-mention";
const myFormatter = {
serialize: (item) => `@${item.id}`,
parse: (text) => [{ kind: "text", text }], // implement your parsing
};
// In composer (textarea path):
...
// In composer (Lexical path — also pass formatter):
...
// In user messages:
const MyDirectiveText = createDirectiveText(myFormatter);
```
Keyboard Navigation \[#keyboard-navigation]
The mention popover supports full keyboard navigation out of the box:
| Key | Action |
| -------------------- | --------------------------------------------- |
| ArrowDown | Highlight next item |
| ArrowUp | Highlight previous item |
| Enter | Select highlighted item / drill into category |
| Escape | Close popover |
| Backspace | Go back to categories (when query is empty) |
Components \[#components]
`ComposerMentionPopover.Root` \[#composermentionpopoverroot]
Wraps the composer with mention context and a tool mention adapter. Provides the `@`-trigger detection, keyboard navigation, and popover state.
| Prop | Type | Default | Description |
| --------------- | ----------------------------- | ------------ | ---------------------------------- |
| `adapter` | `Unstable_MentionAdapter` | Tool adapter | Custom mention adapter |
| `trigger` | `string` | `"@"` | Character(s) that open the popover |
| `formatter` | `Unstable_DirectiveFormatter` | Default | Custom directive serializer/parser |
| `formatLabel` | `(name: string) => string` | Title case | Format tool names for display |
| `categoryLabel` | `string` | `"Tools"` | Label for the tools category |
`ComposerMentionPopover` \[#composermentionpopover]
Pre-built popover containing categories and items lists. Only renders when the `@` trigger is active.
`DirectiveText` \[#directivetext]
A `TextMessagePartComponent` that parses `:type[label]{name=id}` directives and renders them as styled inline chips.
`createDirectiveText(formatter)` \[#createdirectivetextformatter]
Factory function that creates a `TextMessagePartComponent` using a custom `Unstable_DirectiveFormatter`.