8
Hooks

useCopyToClipboard

A hook that provides copy to clipboard functionality with success/error handling.

useCopyToClipboard

The useCopyToClipboard hook provides a simple way to copy text to the user’s clipboard with built-in state tracking for success or failure. It’s perfect for “Copy” buttons in your UI, like sharing links or copying code snippets.

Installation

Install the useCopyToClipboard hook using:

npx axionjs-ui add hook use-copy-to-clipboard

File Structure

use-copy-to-clipboard.ts

Return Value

PropTypeDefault
copy
(text: string) => Promise<boolean>
-
isCopied
boolean
-

Examples

Create a share link button with clipboard functionality:

Custom Reset Duration

If you need a different reset duration for the isCopied state:

function useCustomCopyToClipboard(resetDuration = 2000) {
  const [isCopied, setIsCopied] = useState(false);
  
  useEffect(() => {
    if (isCopied) {
      const timerId = setTimeout(() => {
        setIsCopied(false);
      }, resetDuration);
      
      return () => clearTimeout(timerId);
    }
  }, [isCopied, resetDuration]);
  
  const copy = useCallback(async (text: string): Promise<boolean> => {
    if (!navigator?.clipboard) {
      return false;
    }
    
    try {
      await navigator.clipboard.writeText(text);
      setIsCopied(true);
      return true;
    } catch (error) {
      setIsCopied(false);
      return false;
    }
  }, []);
  
  return { isCopied, copy };
}

Use Cases

  • Code Blocks: Add a copy button to code snippets or examples
  • Share Links: Create easy-to-copy shareable URLs
  • Form Data: Allow users to copy generated content like API keys
  • Citation: Copy properly formatted citations or references
  • Configuration: Copy configuration snippets or environment variables
  • Contact Information: Copy email addresses, phone numbers or addresses
  • Terminal Commands: Copy shell commands without manually selecting text

Accessibility

When implementing clipboard functionality, consider these accessibility improvements:

  • Provide clear visual feedback when content is copied
  • Add appropriate ARIA labels to copy buttons (e.g., aria-label="Copy to clipboard")
  • Ensure the copy button is keyboard accessible
  • Consider adding a tooltip to indicate the button’s purpose
  • Provide screen reader feedback via ARIA live regions when content is copied

Browser Support

The Clipboard API is supported in all modern browsers, but there are some limitations:

  • Only works in secure contexts (HTTPS)
  • May require user permission in some browsers
  • Older browsers may not support the Clipboard API

For better cross-browser compatibility, you could extend this hook with a fallback mechanism:

const copy = useCallback(async (text: string): Promise<boolean> => {
  // Try modern Clipboard API first
  if (navigator?.clipboard) {
    try {
      await navigator.clipboard.writeText(text);
      setIsCopied(true);
      return true;
    } catch (error) {
      // Fall back to document.execCommand
      console.warn("Clipboard API failed, trying fallback...", error);
    }
  }
  
  // Fallback for older browsers
  try {
    const textArea = document.createElement("textarea");
    textArea.value = text;
    textArea.style.position = "fixed";
    textArea.style.opacity = "0";
    document.body.appendChild(textArea);
    textArea.focus();
    textArea.select();
    
    const successful = document.execCommand("copy");
    document.body.removeChild(textArea);
    
    if (successful) {
      setIsCopied(true);
      return true;
    }
  } catch (error) {
    console.error("Fallback clipboard method failed", error);
  }
  
  setIsCopied(false);
  return false;
}, []);

Best Practices

  • Always provide visual feedback when content is copied
  • Reset the copied state after a reasonable timeout (2-3 seconds)
  • Handle errors gracefully and provide fallbacks when possible
  • Consider the content length when copying large amounts of text
  • Respect user permissions and handle rejection gracefully
  • Test on multiple browsers and devices to ensure compatibility

On this page