How to copy text

Joe Medley
Joe Medley

Cutting and pasting text is one of the most commonly used features of apps in general and desktop applications in particular. How do I copy text on the web? There's an old way and a new way. And it depends on which browser is used.

The modern way

Using the Async Clipboard API

The Clipboard.writeText() method takes a string and returns a Promise that resolves when text is successfully written to the clipboard. Clipboard.writeText() can only be used from the window object that has focus.

Browser Support

  • Chrome: 66.
  • Edge: 79.
  • Firefox: 63.
  • Safari: 13.1.

Source

The classic way

Using document.execCommand()

Calling document.execCommand('copy') returns a boolean value that indicates whether the copy was successful. Call this command inside of a user gesture such as a click handler. This approach has limitations when compared to the Async Clipboard API. The execCommand() method only works with DOM elements. Because it's synchronous, copying large amounts of data, especially data that must be transformed or sanitized in some way, can block the page.

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.3.

Source

Progressive enhancement

const copyButton = document.querySelector('#copyButton');
const out = document.querySelector('#out');

if ('clipboard' in navigator) {
  copyButton.addEventListener('click', () => {
    navigator.clipboard.writeText(out.value)
    .then(() => {
      console.log('Text copied');
    })
    .catch((err) => console.error(err.name, err.message));
  });
} else {
  copyButton.addEventListener('click', () => {
    const textArea = document.createElement('textarea');
    textArea.value = out.value;
    textArea.style.opacity = 0;
    document.body.appendChild(textArea);
    textArea.focus();
    textArea.select();
    try {
      const success = document.execCommand('copy');
      console.log(`Text copy was ${success ? 'successful' : 'unsuccessful'}.`);
    } catch (err) {
      console.error(err.name, err.message);
    }
    document.body.removeChild(textArea);
  });
}

Further reading

Demo

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎉</text></svg>"
    />
    <title>How to copy text</title>
  </head>
  <body>
    <h1>How to copy text</h1>
    <textarea rows="3">
Some sample text for you to copy. Feel free to edit this.</textarea
    >
    <button type="button">Copy</button>
  </body>
</html>

CSS


        :root {
  color-scheme: dark light;
}

html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
}

button {
  display: block;
}
        

JS


        const textarea = document.querySelector('textarea');
const button = document.querySelector('button');

button.addEventListener('click', async () => {
  try {
    await navigator.clipboard.writeText(textarea.value);
  } catch (err) {
    console.error(err.name, err.message);
  }
});