# 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