# Each AI response has a copy-to-clipboard button

- **Pattern:** `ab-000140` (`ai-chat-visibility.response-display.copy-response-button`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000140
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000140)

## Why it matters

Users copy AI responses constantly — to paste code into an editor, share an answer in a work chat, or archive an explanation. Forcing manual text selection is a per-message papercut that accumulates across the lifetime of the product, and on mobile it is actively painful: text selection on long messages frequently selects the wrong range or triggers system menus. A per-message copy button is table-stakes for any chat interface that expects repeat use.

## Severity rationale

Low because the workaround is manual selection, but the absence is immediately noticed against every reference product in the category.

## Remediation

In `src/components/chat/MessageBubble.tsx`, add a copy button wired to `navigator.clipboard.writeText()` with a brief checkmark-confirmation state, and reveal it on hover via Tailwind's group/group-hover utilities to keep the resting UI clean.

```tsx
const [copied, setCopied] = useState(false);
const handleCopy = () => {
  navigator.clipboard.writeText(message.content);
  setCopied(true);
  setTimeout(() => setCopied(false), 2000);
};
```

## Detection

- **ID:** `copy-response-button`
- **Severity:** `low`
- **What to look for:** Count all assistant message components and check whether each has a copy button that copies the response text. Look for `navigator.clipboard.writeText()` calls in message components, or a copy icon (Lucide Copy, Clipboard, etc.) rendered per message. This is a standard feature in ChatGPT, Claude, and similar interfaces.
- **Pass criteria:** Each AI response has a copy button that copies the content of that specific message to the clipboard, with visual feedback on copy (e.g., checkmark icon for at least 1 second and no more than 3 seconds).
- **Fail criteria:** No copy button is present on individual messages. Users must manually select and copy text.
- **Skip (N/A) when:** The interface is a kiosk or embedded widget where clipboard access is explicitly not supported by the host environment.
- **Detail on fail:** `"No copy button found on AI message components — users must manually select text to copy responses"`
- **Remediation:** In your message component at `src/components/chat/MessageBubble.tsx`, add a copy button:

  ```tsx
  const [copied, setCopied] = useState(false);
  const handleCopy = () => {
    navigator.clipboard.writeText(message.content);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };
  ```

  The button can appear on hover using CSS group/group-hover to avoid cluttering the UI at rest.

---

Taxons: user-experience

HTML version: https://auditbuffet.com/patterns/ab-000140
