# Quote URL: /docs/ui/quote Let users select and quote text from messages with a floating toolbar, composer preview, and inline quote display. Getting Started \[#getting-started] Add `quote` \[#add-quote] This adds a `/components/assistant-ui/quote.tsx` file with three components: `QuoteBlock`, `SelectionToolbar`, and `ComposerQuotePreview`. 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 ( ); }; ``` 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 ( ... ); }; ``` 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 ( ); }; ``` 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. For alternative backend approaches (Claude SDK citation source, OpenAI message context), see the [Quoting guide](/docs/guides/quoting#backend-handling). Customization \[#customization] All three components expose sub-components for full control over styling: ```tsx // Custom QuoteBlock {text} // Custom SelectionToolbar Reply with quote // Custom ComposerQuotePreview ``` 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