Skip to main content

All hooks

useCopyToClipboard

Custom hook that copies text to the clipboard using the [`Clipboard API`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API).


This hook provides a simple method to copy a string to the clipboard and keeps track of the copied value. If the copying process encounters an issue, it logs a warning in the console, and the copied value remains null.

Usage

import { useCopyToClipboard } from './useCopyToClipboard'

export default function Component() {
  const [copiedText, copy] = useCopyToClipboard()

  const handleCopy = (text: string) => () => {
    copy(text)
      .then(() => {
        console.log('Copied!', { text })
      })
      .catch(error => {
        console.error('Failed to copy!', error)
      })
  }

  return (
    <>
      <h1>Click to copy:</h1>
      <div style={{ display: 'flex' }}>
        <button onClick={handleCopy('A')}>A</button>
        <button onClick={handleCopy('B')}>B</button>
        <button onClick={handleCopy('C')}>C</button>
      </div>
      <p>Copied value: {copiedText ?? 'Nothing is copied yet!'}</p>
    </>
  )
}

API

function useCopyToClipboard(): unknown

Custom hook that copies text to the clipboard using the Clipboard API.

Returns

An tuple containing the copied text and a function to copy text to the clipboard.

Type declaration

CopiedValue

The copied text as string or null if nothing has been copied yet.

CopyFn

Function to copy text to the clipboard.

Hook

import { useCallback, useState } from 'react'

/**
 * The copied text as `string` or `null` if nothing has been copied yet.
 */
export type CopiedValue = string | null

/**
 * Function to copy text to the clipboard.
 * @param text - The text to copy to the clipboard.
 * @returns {Promise<boolean>} A promise that resolves to `true` if the text was copied successfully, or `false` otherwise.
 */
export type CopyFn = (text: string) => Promise<boolean>

/**
 * Custom hook that copies text to the clipboard using the [`Clipboard API`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API).
 * @returns {[CopiedValue, CopyFn]} An tuple containing the copied text and a function to copy text to the clipboard.
 * @public
 * @see [Documentation](https://usehooks-ts.com/react-hook/use-copy-to-clipboard)
 * @example
 * ```tsx
 * const [copiedText, copyToClipboard] = useCopyToClipboard();
 * const textToCopy = 'Hello, world!';
 *
 * // Attempt to copy text to the clipboard
 * copyToClipboard(textToCopy)
 *   .then(success => {
 *     if (success) {
 *       console.log(`Text "${textToCopy}" copied to clipboard successfully.`);
 *     } else {
 *       console.error('Failed to copy text to clipboard.');
 *     }
 *   });
 * ```
 */
export function useCopyToClipboard(): [CopiedValue, CopyFn] {
  const [copiedText, setCopiedText] = useState<CopiedValue>(null)

  const copy: CopyFn = useCallback(async text => {
    if (!navigator?.clipboard) {
      console.warn('Clipboard not supported')
      return false
    }

    // Try to save to clipboard then save it in the state if worked
    try {
      await navigator.clipboard.writeText(text)
      setCopiedText(text)
      return true
    } catch (error) {
      console.warn('Copy failed', error)
      setCopiedText(null)
      return false
    }
  }, [])

  return [copiedText, copy]
}