Skip to content

useCopyToClipboard

What this solves

Copy-to-clipboard is common in admin UIs:

  • Copying API keys, tokens, or IDs
  • Sharing links or codes
  • Copying code snippets

Ad-hoc implementations often miss:

  • Clipboard API availability checks
  • User feedback (success/error toasts)
  • Reset state after copy

useCopyToClipboard provides a consistent copy experience with built-in toast feedback.


When to use it

Use this hook when you need to:

  • Copy text to clipboard with user feedback
  • Show a temporary "copied" state on a button
  • Handle clipboard API errors gracefully

When NOT to use it

  • For complex clipboard operations (images, rich text)
  • When you need custom feedback UI (use the Clipboard API directly)

Basic usage

tsx
import { useCopyToClipboard } from '@/shared/hooks'

export function CopyableCode({ code }: { code: string }) {
  const { copy, copied } = useCopyToClipboard()

  return (
    <div>
      <code>{code}</code>
      <button type="button" onClick={() => copy(code)}>
        {copied ? 'Copied!' : 'Copy'}
      </button>
    </div>
  )
}

With custom messages

tsx
import { useCopyToClipboard } from '@/shared/hooks'

export function ApiKeyDisplay({ apiKey }: { apiKey: string }) {
  const { copy, copied } = useCopyToClipboard({
    successMessage: 'API key copied to clipboard',
    errorMessage: 'Failed to copy API key',
    resetDelay: 3000, // Reset "copied" state after 3 seconds
  })

  return (
    <div>
      <input type="text" value={apiKey} readOnly />
      <button type="button" onClick={() => copy(apiKey)} disabled={copied}>
        {copied ? '✓ Copied' : 'Copy'}
      </button>
    </div>
  )
}

API reference (concise)

ts
interface UseCopyToClipboardOptions {
  successMessage?: string  // Default: 'Code copied!'
  errorMessage?: string    // Default: 'Unable to copy'
  resetDelay?: number      // Default: 2000 (ms)
}

interface UseCopyToClipboardReturn {
  copy: (text: string) => Promise<boolean>
  copied: boolean
  error: Error | null
}

Notes

  • The hook uses the Clipboard API (navigator.clipboard.writeText)
  • Toast notifications are shown automatically via Sonner
  • The copied state resets after resetDelay milliseconds
  • Returns false and shows an error toast if the Clipboard API is unavailable