Copy To Clipboard In JavaScript and React

Learn to copy text to the clipboard in JavaScript and React with examples.

· 3 min read
Copy To Clipboard In JavaScript and React

Copy to Clipboard in JavaScript

To copy text into the clipboard using JavaScript, you can use the Clipboard API:

async function copyToClipboard(text) {
  try {
    await navigator.clipboard.writeText(text);
    /* ✅ Copied successfully */
  } catch (e) {
    /* ❌ Failed to copy (insufficient permissions) */
  }
}
Copy to clipboard example in JavaScript.

The navigator.clipboard.writeText function accepts the text to copy, and returns a Promise:

  • resolved - if the text was copied successfully,
  • rejected - if the user hasn't given the "clipboard-write" permission.

Using Clipboard API in React

You can use the above JavaScript code to implement copying to the clipboard in React, but it's helpful to create a custom hook:

function useCopyToClipboard() {
  const [result, setResult] = useState<
    null | { state: 'success' } | { state: 'error'; message: string }
  >(null);

  const copy = async (text: string) => {
    try {
      await navigator.clipboard.writeText(text);
      setResult({ state: 'success' });
    } catch (e) {
      setResult({ state: 'error', message: e.message });
      throw e;
    } finally {
      // 👇 Show the result feedback for 2 seconds
      setTimeout(() => {
        setResult(null);
      }, 2000);
    }
  };

  // 👇 We want the result as a tuple
  return [copy, result] as const;
}
A custom ReactJS hook to copy text to the clipboard in TypeScript.

The hook returns a tuple with the function to copy text into the clipboard and an object describing the result:

  • null - no text copied recently;
  • "success" - text copied successfully;
  • "error" - operation failed with the error message.

You can use the useCopyToClipboard hook like this:

export function Example() {
  const [inputText, setInputText] = useState('');
  
  // 👇 Using our custom hook
  const [copyToClipboard, copyResult] = useCopyToClipboard();

  const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    setInputText(e.target.value);
  };

  const handleClickCopy = () => {
    // Copy the text from the input field into the clipboard
    copyToClipboard(inputText);
  };

  return (
    <div>
      <input value={inputText} onChange={handleChangeInput} />
      <button onClick={handleClickCopy}>Copy to clipboard</button>
      <div>
      	// 👇 Showing the results in the UI (for 2 seconds)
        {copyResult?.state === 'success' && 'Copied successfully!'}
        {copyResult?.state === 'error' && `Error: ${copyResult.message}`}
      </div>
    </div>
  );
}
Example usage of the custom useCopyToClipboard hook.

The copy operation has no inherent feedback in the UI, so it's a good idea to provide it yourself, you can do that by checking the copyResult value.

Here's what it looks like:

Demo using the custom useCopyToClipboard React hook.

Copy to clipboard button in React

You can also create a CopyToClipboard button component in React that accepts a text prop and handles showing the feedback messages in the UI. Here's an example that uses react-hot-toast:

import toast from 'react-hot-toast';

type Props = React.HTMLAttributes<HTMLButtonElement> & {
  text: string;
};

function CopyToClipboard({ text, children = 'Copy', ...rest }: Props) {
  const handleClickCopy = async () => {
    try {
      await navigator.clipboard.writeText(text);
      // 👇 Using react-hot-toast to provide feedback
      toast.success('Copied!');
    } catch (e) {
      toast.error(`Error: ${e.message}`);
      throw e;
    }
  };

  return (
    <button onClick={handleClickCopy} {...rest}>
      {children}
    </button>
  );
}
Example copy to clipboard button component in React and TypeScript.

Feel free to use the native alert function instead of the toast messages. In that case, replace the toast calls with alert('your message'). However, if you use react-hot-toast you also need to add the Toaster component. Here's an example:

export function Example() {
  const [inputText, setInputText] = React.useState('');

  const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    setInputText(e.target.value);
  };

  return (
    <div>
      {/* 👇 Don't forget to add this */}
      <Toaster />
      <input value={inputText} onChange={handleChangeInput} />
      <CopyToClipboard text={inputText} />
    </div>
  );
}
Example using the CopyToClipboard button.

Here's what it looks like now:

Demo of the CopyToClipboard button.

Conclusion

The simplest way to copy text to the clipboard in JavaScript is by using the Clipboard API. It has good support in modern browsers and it's easy to use.

However, in case you need to support older browsers you can use the copy-to-clipboard npm package, which falls back on using execCommand in case the browser doesn't have access to navigator.clipboard object.

Read about how to get values from the input fields in React next:

How to Get the Value From Input Field in React
The answer to the first question beginners have - how to get a value from an input element.