# Quoted replies

> **Info:** This is release candidate documentation for **Stream Chat React SDK v15**. For the latest stable version, see the [latest version (v14)](https://getstream.io/chat/docs/sdk/react/).

## What users get

A quoted reply answers a specific message without leaving the conversation: the reply carries a copy of the message it answers. It works in channels and threads alike.

- **Quoting.** **Quote Reply** in a message's menu shows the message above the composer's input and moves the focus to the input. The ✕ on the preview removes the quote.
- **The sent reply.** The quoted message appears at the top of the reply's bubble, with its author, its text or a preview of its attachments.
- **Jumping.** Clicking the quoted message jumps to the original in the list and highlights it, loading older messages when it isn't loaded.
- **Staying current.** If the quoted message is edited while the user is writing, the preview updates. If it's deleted, the quote is removed.

## How it works across the layers

The user wants to answer Ben's question from earlier in "Design":

1. They pick **Quote Reply** on Ben's message. The action calls `MessageComposer.setQuotedMessage(message)` on the composer they type in: the channel's, or the thread's inside a thread.
2. The composer keeps the message in its state as `quotedMessage`. `QuotedMessagePreview` reads it and shows it above the input.
3. The user sends their reply. The composer adds `quoted_message_id` to the request, and a copy of the quoted message to the local message, so the reply shows the quote while it's sending.
4. In the message list, `QuotedMessage` renders `message.quoted_message`. Clicking it calls `MessagePaginator.jumpToMessage()` on the list's message paginator.

While a message is quoted, commands of the moderation set are disabled in the composer. A draft keeps its quote, and restoring the draft brings it back. Removing the quote is `MessageComposer.setQuotedMessage(null)`.

The composer's state and its parts are on [Message composer](https://getstream.io/chat/docs/sdk/react/v15/state/writing-messages/message-composer/), and the composer's previews on [Message composer UI](https://getstream.io/chat/docs/sdk/react/v15/ui/components/message-composer-ui/#previews). How the list jumps to a message is on [Jumping and highlighting](https://getstream.io/chat/docs/sdk/react/v15/state/loading-data/message-paginators/#jumping-and-highlighting).

## Turning it on or off

Quoted replies are always available. Two things decide who can use them:

- The `quote-message` capability. Without it, the message menu leaves out **Quote Reply**. The server derives it from the user's role and the channel type's settings, which include `quotes`.
- The `disableQuotedMessages` prop of `MessageList`, which removes **Quote Reply** from that list. `VirtualizedMessageList` doesn't have it; remove the action from the action set there instead, as described on [Actions](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/actions/#message-actions).

## Customizing

### Quoting from your own control

Any component inside a `Channel` or `Thread` can quote a message through the composer:

```tsx
import type { LocalMessage } from "stream-chat";
import { useMessageComposerController } from "stream-chat-react";

export const QuoteButton = ({ message }: { message: LocalMessage }) => {
  const composer = useMessageComposerController();

  return (
    <button onClick={() => composer.setQuotedMessage(message)} type="button">
      Quote
    </button>
  );
};
```

To put it in the message menu, add it to the message action set; see [Actions](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/actions/).

### Replacing the preview in the composer

`QuotedMessagePreview` is an override key. A replacement reads `quotedMessage` from the composer's state:

```tsx
import type { MessageComposerState } from "stream-chat";
import {
  useMessageComposerController,
  useStateStore,
  WithComponents,
} from "stream-chat-react";

const quoteSelector = (state: MessageComposerState) => ({
  quotedMessage: state.quotedMessage,
});

const CompactQuotePreview = () => {
  const composer = useMessageComposerController();
  const { quotedMessage } = useStateStore(composer.state, quoteSelector);

  if (!quotedMessage) return null;

  return (
    <div className="compact-quote-preview">
      Replying to {quotedMessage.user?.name ?? "a message"}
      <button onClick={() => composer.setQuotedMessage(null)} type="button">
        Cancel
      </button>
    </div>
  );
};

export const App = () => (
  <WithComponents overrides={{ QuotedMessagePreview: CompactQuotePreview }}>
    {/* the rest of the app */}
  </WithComponents>
);
```

While the user edits a message, the composer shows `EditedMessagePreview` in its place.

### Replacing the quote in a message

`QuotedMessage` renders the quote inside a sent message. A replacement reads the message from `useMessageContext()`:

```tsx
import {
  useMessageContext,
  useMessagePaginator,
  WithComponents,
} from "stream-chat-react";

const QuoteLine = () => {
  const { message } = useMessageContext();
  // Inside a thread, the original is in the thread's replies, which this list holds.
  const messagePaginator = useMessagePaginator();
  const quoted = message.quoted_message;

  if (!quoted) return null;

  return (
    <button
      className="quote-line"
      onClick={() => messagePaginator.jumpToMessage(quoted.id)}
      type="button"
    >
      {quoted.user?.name}: {quoted.text}
    </button>
  );
};

export const App = () => (
  <WithComponents overrides={{ QuotedMessage: QuoteLine }}>
    {/* the rest of the app */}
  </WithComponents>
);
```

The jump itself is explained on [Jumping and highlighting](https://getstream.io/chat/docs/sdk/react/v15/state/loading-data/message-paginators/#jumping-and-highlighting).

## Reference

- State: [Message composer](https://getstream.io/chat/docs/sdk/react/v15/state/writing-messages/message-composer/) and the [MessageComposer API](https://getstream.io/chat/docs/sdk/react/v15/reference/state/messagecomposer-api/).
- UI: [Message composer UI](https://getstream.io/chat/docs/sdk/react/v15/ui/components/message-composer-ui/#previews), [Message list UI](https://getstream.io/chat/docs/sdk/react/v15/ui/components/message-list-ui/#a-message) and [Overriding components](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/overriding-components/).
- Props: [Composer UI components](https://getstream.io/chat/docs/sdk/react/v15/component-reference/message-composer/composer-ui-components/), [Message UI components](https://getstream.io/chat/docs/sdk/react/v15/component-reference/message/message-ui-components/) and [MessageList](https://getstream.io/chat/docs/sdk/react/v15/component-reference/message-list/messagelist/).
- Hooks: [Composer hooks](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/composer-hooks/).

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v15/features/messaging/quoted-replies/](https://getstream.io/chat/docs/sdk/react/v15/features/messaging/quoted-replies/).