useCopyToClipboard

Copy text to the clipboard

4a5e1e8e-37e8-4154-82e9-6c53e0cdb567

Installation

Copy-paste the hook

Copy and paste the hook code in a .ts file.

import { useCallback, useState } from 'react';
 
/**
 * A custom hook that provides a way to copy text to the clipboard.
 *
 * @param {number} [timeoutDuration=1000] - The duration in milliseconds to wait before clearing the copied text.
 *
 * @returns An object containing the following properties:
 *  - `isCopied`: A boolean indicating whether the text has been copied to the clipboard.
 *  - `copyToClipboard`: A function that takes a string as an argument and attempts to copy it to the clipboard.
 *  - `error`: An optional error object that can be used to handle any errors that occur during the copy operation.
 *
 * @example
 * const { isCopied, copyToClipboard } = useCopyToClipboard();
 * copyToClipboard('Text to copy');
 */
export const useCopyToClipboard = (timeoutDuration = 1000) => {
  const [isCopied, setIsCopied] = useState(false);
  const [error, setError] = useState<Error | null>(null);
 
  const oldSchoolCopy = (text: string) => {
    const tempTextArea = document.createElement('textarea');
    tempTextArea.value = text;
    document.body.appendChild(tempTextArea);
    tempTextArea.select();
    document.execCommand('copy');
    document.body.removeChild(tempTextArea);
  };
 
  const copyToClipboard = useCallback(
    async (text: string) => {
      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
      if (navigator?.clipboard?.writeText) {
        try {
          await navigator.clipboard.writeText(text);
          setIsCopied(true);
          setError(null);
          setTimeout(() => setIsCopied(false), timeoutDuration);
          return true;
        } catch (error) {
          setError(
            error instanceof Error ? error : new Error('Failed to copy text'),
          );
          return false;
        }
      } else {
        try {
          oldSchoolCopy(text);
          setIsCopied(true);
          setError(null);
          setTimeout(() => setIsCopied(false), timeoutDuration);
          return true;
        } catch (error) {
          setError(
            error instanceof Error ? error : new Error('Failed to copy text'),
          );
          return false;
        }
      }
    },
    [timeoutDuration],
  );
 
  return { isCopied, copyToClipboard, error };
};

Usage

import { useCopyToClipboard } from '~/hooks/use-copy-to-clipboard';
const { isCopied, copyToClipboard } = useCopyToClipboard();
 
copyToClipboard('Text to copy');
isCopied ? <span>Copied!</span> : <span>Copy to clipboard</span>;

Details

Clipboard Copying Mechanism

  • The hook provides a seamless way to copy text to the clipboard using the modern navigator.clipboard API when available. This ensures a secure and reliable copying experience.
  • If the navigator.clipboard API is not supported (e.g., in older browsers), the hook falls back to an old-school method using a temporary <textarea> element and the document.execCommand('copy') method.

State Management

  • isCopied: A boolean state that indicates whether the text has been successfully copied to the clipboard. This can be used to provide user feedback (e.g., showing a "Copied!" message).
  • error: An optional state that captures any errors that occur during the copy operation. This allows for better error handling and user notifications.

Timeout for Resetting State

  • The hook includes a timeoutDuration parameter (defaulting to 1000 milliseconds) that determines how long the isCopied state remains true before resetting to false. This feature helps in providing temporary feedback to users after a copy action.
  • The timeout can be customized by passing a different value when using the hook, allowing for flexibility based on user interface requirements.

Return Value

  • The hook returns an object containing:
  • isCopied: A boolean indicating whether the text has been copied successfully.
  • copyToClipboard: A function that takes a string as an argument and attempts to copy it to the clipboard. It returns a promise that resolves to a boolean indicating the success of the operation.
  • error: An optional error object that can be used to handle any errors that occur during the copy operation.

On this page