# Directive Text
URL: /docs/ui/directive-text

Render mention directives as inline chips in user messages.

<DirectiveTextSample />

`DirectiveText` parses the directive syntax written by [`ComposerTriggerPopover`](/docs/ui/composer-trigger-popover) (default: `:type[label]{name=id}`) and renders each segment as an inline chip. Use it as the `Text` component in user messages so the raw directive syntax never shows up.

Getting Started \[#getting-started]

<Steps>
  <Step>
    Add `directive-text` \[#add-directive-text]

    <InstallCommand shadcn="[&#x22;directive-text&#x22;]" />

    This adds `/components/assistant-ui/directive-text.tsx` with `DirectiveText` and the `createDirectiveText(formatter, options?)` factory.
  </Step>

  <Step>
    Use in user messages \[#use-in-user-messages]

    Pass `DirectiveText` as the `Text` component in `MessagePrimitive.Parts`:

    ```tsx title="components/assistant-ui/thread.tsx"
    import { DirectiveText } from "@/components/assistant-ui/directive-text";

    const UserMessage = () => (
      <MessagePrimitive.Root>
        <MessagePrimitive.Parts components={{ Text: DirectiveText }} />
      </MessagePrimitive.Root>
    );
    ```

    Keep your markdown renderer (e.g. `MarkdownText`) for assistant messages — assistants rarely emit directive syntax.
  </Step>
</Steps>

Icons per Directive Type \[#icons-per-directive-type]

`DirectiveText` ships icon-free by default — every parsed segment renders as a plain label chip regardless of its `type`. To add icons, use the `createDirectiveText` factory and pass an `iconMap` that routes each `type` string to an icon component, plus an optional `fallbackIcon` for unmapped types:

```tsx
import { createDirectiveText } from "@/components/assistant-ui/directive-text";
import { unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
import { FileTextIcon, SparklesIcon, UserIcon, WrenchIcon } from "lucide-react";

const DirectiveTextWithIcons = createDirectiveText(
  unstable_defaultDirectiveFormatter,
  {
    iconMap: {
      tool: WrenchIcon,
      user: UserIcon,
      file: FileTextIcon,
    },
    fallbackIcon: SparklesIcon,
  },
);

<MessagePrimitive.Parts components={{ Text: DirectiveTextWithIcons }} />;
```

A matching `iconMap` / `fallbackIcon` option is accepted by [`ComposerTriggerPopover`](/docs/ui/composer-trigger-popover), where it routes `item.metadata.icon` strings instead of `type` — keeping icon configuration consistent across the composer and the rendered message.

Custom Formatter \[#custom-formatter]

The default format is `:type[label]{name=id}`. For a different format, build a custom `Unstable_DirectiveFormatter` and wrap it with `createDirectiveText`:

```tsx
import type { Unstable_DirectiveFormatter } from "@assistant-ui/core";
import { createDirectiveText } from "@/components/assistant-ui/directive-text";

const slashFormatter: Unstable_DirectiveFormatter = {
  serialize: (item) => `/${item.id}`,
  parse: (text) => {
    /* return alternating text / mention segments */
  },
};

const SlashDirectiveText = createDirectiveText(slashFormatter);
```

Pass the **same formatter** to the composer trigger's `directive={{ formatter }}` (or `action={{ formatter }}`) so insertion and rendering stay consistent.

Customizing the Chip \[#customizing-the-chip]

Because `directive-text.tsx` is copied into your project, you can also edit it directly — swap the chip styling, read `data-directive-id` to link to a detail page, or replace the chip wrapper entirely.

API Reference \[#api-reference]

`DirectiveText` \[#directivetext]

A `TextMessagePartComponent` that parses `:type[label]{name=id}` directives and renders them as inline chips. Uses the default formatter from `@assistant-ui/core` and renders chips without icons. For per-type icons, build a component with `createDirectiveText(formatter, { iconMap })`.

`createDirectiveText(formatter, options?)` \[#createdirectivetextformatter-options]

Factory that returns a `TextMessagePartComponent` bound to a custom `Unstable_DirectiveFormatter`.

| Option         | Type                                                    | Description                                                                                                |
| -------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `iconMap`      | `Record<string, ComponentType<{ className?: string }>>` | Maps a directive segment's `type` to an icon rendered inside the chip                                      |
| `fallbackIcon` | `ComponentType<{ className?: string }>`                 | Icon used when no `iconMap` entry matches. When neither option resolves, the chip renders without an icon. |

Related \[#related]

* [Composer Trigger Popover](/docs/ui/composer-trigger-popover) — the picker that inserts directives
* [Mentions guide](/docs/guides/mentions) — directive format, backend parsing
