How to Copy to clipboard with Javascript.

Learn how to copy text to clipboard with javascript.

You may have encountered a situation while building a website to allow users to copy text from your website on some events. I have a similar functionality here to copy the code snippets.

Let us see how you can add the same to your website to copy the content.

Copying text to clipboard can be done in 5 simple steps.

  1. Create a <textarea> element and append it to our HTML document.
  2. Fill the text or content you want to copy in this <textarea>.
  3. Use HTMLElement.select() to select the contents of this <textarea>.
  4. Copy the content of the <textarea> using Document.execCommand(‘copy’).
  5. Remove the <textarea>.

Here is the code for the simplest working version.

const copyText = str => {
  //Create new element
  const elm = document.createElement('textarea');
  
  //Fill the new element with text
  elm.value = str;
  
  //Append the new element
  document.body.appendChild(elm);
  
  //Select the content of the element
  elm.select();
  
  //Copy the content
  document.execCommand('copy');
  
  //Remove the element
  document.body.removeChild(elm);
};

Now this is a pure function which will copy the content on event like click or change. And you have to pass the text to it for copying.

It may seem to be working fine but there is some issue with this.
1. The <textarea> element which we are adding to the DOM will be visible which is a bad user experience.
2. Users may have selected some content on the HTML document which will be refreshed after this action, so we have to restore the original selection.

Hiding the appeneded element.

We can style the <textarea> so that it is not visible on the DOM but still be able to perform its work.

const copyText = str => {
  //Create new element
  const elm = document.createElement('textarea');
  
  //Fill the new element with text
  elm.value = str;
  
  //Hiding the appended element.
  elm.setAttribute('readonly', '');
  elm.style.position = 'absolute';
  elm.style.left = '-9999px';
  
  //Append the new element
  document.body.appendChild(elm);
  
  //Select the content of the element
  elm.select();
  
  //Copy the content
  document.execCommand('copy');
  
  //Remove the element
  document.body.removeChild(elm);
};

Restoring original document’s selection

It may happen that users may have already selected something on the DOM so it would not be nice to remove that.

To our luck, we can use some new javascript like DocumentOrShadowRoot.getSelection(), Selection.rangeCount, Selection.getRangeAt(), Selection.removeAllRanges() and Selection.addRange() to save and restore original document selection.

const copyText = str => {
  //Create new element
  const elm = document.createElement('textarea');
  
  //Fill the new element with text
  elm.value = str;
  
  //Hiding the appended element.
  elm.setAttribute('readonly', '');
  elm.style.position = 'absolute';
  elm.style.left = '-9999px';
  
  //Append the new element
  document.body.appendChild(elm);
  
  // Check if there is any content selected previously
  const selected =            
    document.getSelection().rangeCount > 0        
      ? document.getSelection().getRangeAt(0)     // Store selection if found
      : false;                                    // Mark as false to know no selection existed before
  
  // Select the <textarea> content
  el.select();    
  
  // Copy - only works as a result of a user action (e.g. click events)
  document.execCommand('copy'); 
  
  // Remove the <textarea> element
  document.body.removeChild(el); 
  
  // If a selection existed before copying
  if (selected) {                                 
    document.getSelection().removeAllRanges();    // Unselect everything on the HTML document
    document.getSelection().addRange(selected);   // Restore the original selection
  }
};

There is another way if you want to copy the text to the clipboard in javascript by directly clicking or performing an action on them.

The Clipboard API is available on the navigator.clipboard object.

The Clipboard API is relatively recent and not all browsers implement it. It works on Chrome, modern Edge (chromium-based), Firefox and Opera.

We can check if it is supported or not.

if (!navigator.clipboard) {
  // Clipboard API not available
  return
}

One thing you must now understand is that you can’t copy/paste from the clipboard without the user’s permission.

The permission is different if you’re reading or writing to the clipboard. In case you are writing, all you need is the user’s intent: you need to put the clipboard action in a response to a user action, like a click.

Writing text to the clipboard

Suppose we have a paragraph element and we want to copy its content.

<p>Master DSA with Javascript</p>

And when we clicking on this text we want it to be copied on the clipboard. So we assign an event listener to it.

document.querySelector('p').addEventListener('click', async event => {
  if (!navigator.clipboard) {
    // Clipboard API not available
    return;
  }
});

Then we call navigator.clipboard.writeText() and to copy the text of the paragraph element to the clipboard. As it is an asynchronous process we will use async/await.

document.querySelector('p').addEventListener('click', async event => {
  if (!navigator.clipboard) {
    // Clipboard API not available
    return;
  }

  //Get the paragraph text
  const text = event.target.innerText
  try {
    //Write it to the clipboard
    await navigator.clipboard.writeText(text);

    //Change text to notify user
    event.target.textContent = 'Copied to clipboard';
  } catch (err) {
    console.error('Failed to copy!', err);
  }
})

After we have written the content on the clipboard we can also read it from there.


Reading text from the clipboard

Getting the copied content from the clipboard.

<p>Master Full stack development with Javascript</p>

And when we clicking on this text we want it to be changed from the content we have copied.

document.querySelector('p').addEventListener('click', async event => {
  if (!navigator.clipboard) {
    // Clipboard API not available
    return;
  }
});

Then we call navigator.clipboard.readText() and get the copied text from the clipboard. As it is an asynchronous process we will use async/await.

document.querySelector('p').addEventListener('click', async event => {
  if (!navigator.clipboard) {
    // Clipboard API not available
    return;
  }
  try {
    //Get the copied text
    const text = await navigator.clipboard.readText();

    //Pass it to the element.
    event.target.textContent = text;
  } catch (err) {
    console.error('Failed to copy!', err);
  }
});

The first time you execute this code on your site, you’ll see this box appearing and asking for permission. You need to provide it to copy the content.