DEV Community

Cover image for The Right Way to Copy to Clipboard in React (2024)
Samitha Widanage
Samitha Widanage

Posted on

The Right Way to Copy to Clipboard in React (2024)

Copying to clipboard seems simple, right? Click a button, text goes to clipboard. Done.

But if you've ever tried implementing this in React, you know it's not that straightforward. I built @samithahansaka/clipboard to solve this once and for all.

## The Problem with Existing Solutions

react-copy-to-clipboard - 500K+ weekly downloads, but:

  • No hooks API (class component wrapper)
  • No rich content (HTML) support

Manual implementation - Copy-paste from Stack Overflow:

  • Doesn't handle fallbacks properly
  • No state management for "Copied!" feedback
  • SSR issues with Next.js/Remix

**Introducing @samithahansaka/clipboard

Install:

  npm install @samithahansaka/clipboard                                                                                                             
Enter fullscreen mode Exit fullscreen mode

Features:

  • Hooks API ✅
  • Component API ✅
  • HTML/Rich content ✅
  • TypeScript first-class ✅
  • Bundle size ~1KB
  • Zero dependencies
  • SSR-safe ✅

Basic Usage

  import { useCopyToClipboard } from '@samithahansaka/clipboard';                                                                                   

  function CopyButton() {                                                                                                                           
    const { copy, copied } = useCopyToClipboard();                                                                                                  

    return (                                                                                                                                        
      <button onClick={() => copy('Hello, World!')}>                                                                                                
        {copied ? '✓ Copied!' : 'Copy'}                                                                                                             
      </button>                                                                                                                                     
    );                                                                                                                                              
  }                                                                                                                                                 
Enter fullscreen mode Exit fullscreen mode

Copying Rich HTML Content

  const { copy } = useCopyToClipboard();                                                                                                            

  copy({                                                                                                                                            
    text: 'Hello, World!',                                                                                                                          
    html: '<strong>Hello, World!</strong>'                                                                                                          
  });                                                                                                                                               
Enter fullscreen mode Exit fullscreen mode

When pasted into:

  • Notepad/Terminal: Gets "Hello, World!"
  • Google Docs/Email: Gets Hello, World! (bold)

Integration with Toast Libraries

  import { useCopyToClipboard } from '@samithahansaka/clipboard';                                                                                   
  import { toast } from 'sonner';                                                                                                                   

  function ShareButton({ url }) {                                                                                                                   
    const { copy } = useCopyToClipboard({                                                                                                           
      onSuccess: () => toast.success('Link copied!'),                                                                                               
      onError: () => toast.error('Failed to copy'),                                                                                                 
    });                                                                                                                                             

    return <button onClick={() => copy(url)}>Share</button>;                                                                                        
  }                                                                                                                                                 
Enter fullscreen mode Exit fullscreen mode

Component API

  import { CopyButton } from '@samithahansaka/clipboard';                                                                                           

  function App() {                                                                                                                                  
    return (                                                                                                                                        
      <CopyButton content="Text to copy">                                                                                                           
        {({ copy, copied }) => (                                                                                                                    
          <button onClick={copy}>                                                                                                                   
            {copied ? 'Done!' : 'Copy'}                                                                                                             
          </button>                                                                                                                                 
        )}                                                                                                                                          
      </CopyButton>                                                                                                                                 
    );                                                                                                                                              
  }                                                                                                                                                 
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. Modern browsers: Uses navigator.clipboard.write()
  2. Older browsers: Falls back to navigator.clipboard.writeText()
  3. Legacy browsers: Falls back to document.execCommand('copy')

Links

If this helped you, consider giving the repo a ⭐ on GitHub!

Top comments (0)