---
title: Copy Button
description: A button with a copy to clipboard animation and optional text label.
icon: copy
author:
  name: imskyleen
  url: https://github.com/imskyleen
mode: wide
---

<PoweredBy
  packages={[
    { name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/button' },
    { name: 'Animate UI', url: 'https://animate-ui.com/docs/buttons/copy' },
    { name: 'Lucide', url: 'https://lucide.dev/' },
    { name: 'Motion', url: 'https://motion.dev/' },
  ]}
/>

### Installation

```package-install
npx shadcn@latest add @redpanda/copy-button
```

<ComponentPreview name="copy-button-demo" />

## When to use

Use this decision tree to determine when to use the Copy Button component:

```mermaid
graph TD;
    A[❓ Need to copy content to clipboard?] --> B{What type of content?};
    B --> C[✅ Short text/tokens];
    B --> D[✅ Code snippets];
    B --> E[✅ URLs/links];
    B --> F[⚠️ Large text blocks];

    C --> G[❓ Where to place button?];
    D --> H[ℹ️ Consider CodeBlock with copy];
    E --> G;
    F --> I[⚠️ Provide textarea with select-all];

    G --> J[✅ Inline with content];
    G --> K[✅ Standalone action];
    H --> L[❓ Custom styling needed?];

    J --> M[❓ Need visual feedback?];
    K --> M;
    L --> N[✅ Use CopyButton for consistency];
    L --> O[ℹ️ Use built-in CodeBlock copy];

    M --> P["✅ Default animation (3s delay)"];
    M --> Q[✅ Custom delay timing];

    P --> R[❓ Button styling?];
    Q --> S[✅ Set custom delay prop];

    R --> T["✅ Match existing UI (variant prop)"];
    R --> U[ℹ️ Use default variant];
    S --> T;

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class C,D,E,J,K,N,P,Q,S,T recommended;
    class F,I discouraged;
    class A,B,G,L,M,R decision;
    class H,O,U neutral;
```

## Motion features

CopyButton includes its synchronous Motion features; no application-level LazyMotion provider is required. Its HTMLMotionProps contract still supports drag and layout animations, and it inherits an enclosing MotionConfig, including reduced-motion preferences.

## Usage

### Icon Only

```tsx
<CopyButton content="Hello world!" size="icon" />
```

### With Text Label

```tsx
<CopyButton content="npm install @redpanda/ui">Copy</CopyButton>
```

### Different Variants

```tsx
<CopyButton content="Hello world!" variant="outline">
  Copy to clipboard
</CopyButton>

<CopyButton content="Some text" variant="default">
  Copy text
</CopyButton>

<CopyButton content="Code snippet" variant="ghost">
  Copy
</CopyButton>
```

### When the write is refused

No permission, no secure context, no clipboard API: the button swaps to an X for `delay` and renders a
`role="alert"` region beside itself. The icon span carries `data-state="idle" | "copied" | "error"`, and
an icon-only button is named "Copy" unless you pass an `aria-label`.

## Props

| Prop | Type | Default | Description |
| - | - | - | - |
| `content?` | `string` | - | The content to copy to the clipboard. |
| `children?` | `React.ReactNode` | - | Optional text label to display next to the icon. |
| `delay?` | `number` | `3000` | The delay in milliseconds before the button resets. |
| `size?` | `'sm' \| 'md' \| 'lg' \| 'icon' \| 'icon-xs'` | `md` | The size of the button. |
| `variant?` | `'default' \| 'destructive' \| 'outline' \| 'secondary' \| 'ghost'` | `default` | The variant of the button. |
| `onCopy?` | `(content: string) => void` | - | The function to call when copy is successful. |

## Credits

- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/button) for the button style.
- We use [Animate UI](https://github.com/animate-ui/animate-ui) from [imskyleen](https://github.com/imskyleen) for all the animations.
