# Quote
URL: /docs/ui/quote

Let users select and quote text from messages with a floating toolbar, composer preview, and inline quote display.

<QuoteSample />

Getting Started \[#getting-started]

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

    <InstallCommand shadcn="[&#x22;quote&#x22;]" />

    This adds a `/components/assistant-ui/quote.tsx` file with three components: `QuoteBlock`, `SelectionToolbar`, and `ComposerQuotePreview`.
  </Step>

  <Step>
    Display Quotes in User Messages \[#display-quotes-in-user-messages]

    Pass `QuoteBlock` to `MessagePrimitive.Parts` as the `Quote` renderer:

    ```tsx title="components/assistant-ui/thread.tsx" {1,8}
    import { QuoteBlock } from "@/components/assistant-ui/quote";

    const UserMessage = () => {
      return (
        <MessagePrimitive.Root>
          <MessagePrimitive.Parts
            components={{
              Quote: QuoteBlock,
            }}
          />
        </MessagePrimitive.Root>
      );
    };
    ```
  </Step>

  <Step>
    Add the Floating Selection Toolbar \[#add-the-floating-selection-toolbar]

    Render `SelectionToolbar` inside `ThreadPrimitive.Root`. It portals to the document body and appears near the user's text selection.

    ```tsx title="components/assistant-ui/thread.tsx" {1,11}
    import { SelectionToolbar } from "@/components/assistant-ui/quote";

    const Thread = () => {
      return (
        <ThreadPrimitive.Root>
          <ThreadPrimitive.Viewport>
            <ThreadPrimitive.Messages components={{ ... }} />
            ...
          </ThreadPrimitive.Viewport>

          <SelectionToolbar />
        </ThreadPrimitive.Root>
      );
    };
    ```
  </Step>

  <Step>
    Show Quote Preview in Composer \[#show-quote-preview-in-composer]

    Add `ComposerQuotePreview` inside your composer. It only renders when a quote is set.

    ```tsx title="components/assistant-ui/thread.tsx" {1,6}
    import { ComposerQuotePreview } from "@/components/assistant-ui/quote";

    const Composer = () => {
      return (
        <ComposerPrimitive.Root>
          <ComposerQuotePreview />
          <ComposerPrimitive.Input placeholder="Send a message..." />
          <ComposerPrimitive.Send />
        </ComposerPrimitive.Root>
      );
    };
    ```
  </Step>

  <Step>
    Forward Quote Context to the LLM \[#forward-quote-context-to-the-llm]

    Quote data is stored in message metadata, **not** in message content. Use `injectQuoteContext` in your route handler so the LLM sees the quoted text:

    ```typescript title="app/api/chat/route.ts" {2,9}
    import { convertToModelMessages, streamText } from "ai";
    import { injectQuoteContext } from "@assistant-ui/react-ai-sdk";

    export async function POST(req: Request) {
      const { messages } = await req.json();

      const result = streamText({
        model: myModel,
        messages: await convertToModelMessages(injectQuoteContext(messages)),
      });

      return result.toUIMessageStreamResponse();
    }
    ```

    `injectQuoteContext` prepends the quoted text as a markdown `>` blockquote to the message parts so the LLM receives the context the user is referring to.

    <Callout>
      For alternative backend approaches (Claude SDK citation source, OpenAI message context), see the [Quoting guide](/docs/guides/quoting#backend-handling).
    </Callout>
  </Step>
</Steps>

Customization \[#customization]

All three components expose sub-components for full control over styling:

```tsx
// Custom QuoteBlock
<QuoteBlock.Root className="my-custom-class">
  <QuoteBlock.Icon />
  <QuoteBlock.Text>{text}</QuoteBlock.Text>
</QuoteBlock.Root>

// Custom SelectionToolbar
<SelectionToolbar.Root>
  <SelectionToolbar.Quote>Reply with quote</SelectionToolbar.Quote>
</SelectionToolbar.Root>

// Custom ComposerQuotePreview
<ComposerQuotePreview.Root>
  <ComposerQuotePreview.Icon />
  <ComposerQuotePreview.Text />
  <ComposerQuotePreview.Dismiss />
</ComposerQuotePreview.Root>
```

API Reference \[#api-reference]

`QuoteBlock` \[#quoteblock]

Renders quoted text in user messages. Pass to `MessagePrimitive.Parts` as `components.Quote`.

| Prop        | Type     | Description              |
| ----------- | -------- | ------------------------ |
| `text`      | `string` | The quoted text          |
| `messageId` | `string` | ID of the source message |

**Sub-components:** `QuoteBlock.Root`, `QuoteBlock.Icon`, `QuoteBlock.Text`

`SelectionToolbar` \[#selectiontoolbar]

Floating toolbar that appears when text is selected within a message. Renders as a portal positioned above the selection.

| Prop        | Type     | Description            |
| ----------- | -------- | ---------------------- |
| `className` | `string` | Additional class names |

**Sub-components:** `SelectionToolbar.Root`, `SelectionToolbar.Quote`

`ComposerQuotePreview` \[#composerquotepreview]

Quote preview inside the composer. Only renders when a quote is set.

| Prop        | Type     | Description            |
| ----------- | -------- | ---------------------- |
| `className` | `string` | Additional class names |

**Sub-components:** `ComposerQuotePreview.Root`, `ComposerQuotePreview.Icon`, `ComposerQuotePreview.Text`, `ComposerQuotePreview.Dismiss`

`injectQuoteContext` \[#injectquotecontext]

```typescript
import { injectQuoteContext } from "@assistant-ui/react-ai-sdk";

injectQuoteContext(messages: UIMessage[]): UIMessage[]
```

Extracts `metadata.custom.quote` from each message and prepends the quoted text as a `> blockquote` text part. Use before `convertToModelMessages` in your route handler. For alternative backend approaches, see the [Quoting guide](/docs/guides/quoting#backend-handling).

`useMessageQuote` \[#usemessagequote]

```tsx
import { useMessageQuote } from "@assistant-ui/react";

const quote: QuoteInfo | undefined = useMessageQuote();
```

Returns the quote attached to the current message, or `undefined`. Useful for building custom quote displays without `QuoteBlock`. For a usage example, see the [Quoting guide](/docs/guides/quoting#reading-quote-data).

`ComposerRuntime.setQuote` \[#composerruntimesetquote]

```tsx
setQuote(quote: QuoteInfo | undefined): void
```

Set or clear the quote on the composer programmatically. The quote is automatically cleared when the message is sent. For a usage example, see the [Quoting guide](/docs/guides/quoting#programmatic-api).

Related \[#related]

* [Quoting guide](/docs/guides/quoting): Backend handling, programmatic API, data shape, and design notes
* [Thread](/docs/ui/thread): Main chat container
