# 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`.