DEV Community

Carme Mias
Carme Mias

Posted on • Updated on

Copy HTML content with navigator clipboard

We have often seen “Copy” buttons for plain text. Thanks to navigator.clipboard‘s API, we can also programatically copy and paste HTML content.

The copy code

Let’s imagine we have a bit of HTML content that includes links and other basic HTML code. We want our end users to be able to copy it exactly as it is and use it elsewhere.

For this exercise, we will be working with a simple HTML page with a section with id=”copy-content” that contains the HTML to be copied, and a “Copy to clipboard” button, with id=”copy-button”. The code for this example can be found in this gist.

Initially, the javascript that makes it all happen looks like this:

const copyButton = document.getElementById("copy-button");
copyButton.addEventListener("click", copyContent);

function copyContent() {
  const content = document.getElementById("copy-content").innerHTML;
  addHtmlToClipboard(content);
}

function addHtmlToClipboard(content) {
  const type = "text/html";
  const blob = new Blob([content], { type });
  const data = [new ClipboardItem({ [type]: blob })];

  navigator.clipboard.write(data).then(
    () => {
      console.log("copied to clipboard");
    },
    () => {
      console.log("failed to copy to clipboard");
    },
  );
}
Enter fullscreen mode Exit fullscreen mode

First, we add a “click” event to the “Copy to clipboard” button so that, when the button is clicked, the copyContent function is executed.

This copyContent function, gets the HTML content we want to copy and passes it to the addHtmlToClipboard function.

The addHtmlToClipboard function then takes this content, converts it into an HTML Blob and creates a new ClipboardItem with it. This is then writen into the clipboard using navigator.clipboard.write.

If the clipboard API succedes, the content is ready to be pasted elsewhere. For example, in a Word document or an email.

Note the inline CSS it is also copied but not that which is in a separate file.

Firefox gotcha

Unfortunately the ClipboardItem funtionality is not yet supported by all browsers, notably Firefox.

As a compromise, we can change the code so that at least the text content is copied to clipboard if the full functionality cannot be used. Here is the updated code:

const copyButton = document.getElementById("copy-button");
copyButton.addEventListener("click", copyContent);

function copyContent() {
  const content = document.getElementById("copy-content").innerHTML;

  if(typeof ClipboardItem === "function") {
    addHtmlToClipboard(content);
  } else {
    const textContent = sanitize(content);
    addTextToClipboard(textContent);
  }
}

function addHtmlToClipboard(content) {
  const type = "text/html";
  const blob = new Blob([content], { type });
  const data = [new ClipboardItem({ [type]: blob })];

  navigator.clipboard.write(data).then(
    () => {
      console.log("copied html to clipboard");
    },
    () => {
      console.log("failed to copy html to clipboard");
    },
  );
}

// removes all HTML tags and empty spaces at either end
function sanitize(content) {
  const pattern = /<\/?[\w ="'-:;\/\.]+>/g;

  return content.replaceAll(pattern, "").trim();
}

function addTextToClipboard(text) {
  navigator.clipboard.writeText(text).then(
    () => {
      console.log("copied text to clipboard");
    },
    () => {
      console.log("failed to copy text to clipboard");
    },
  );
}
Enter fullscreen mode Exit fullscreen mode

So what has changed? First of all, after getting the content to be copied, the copyContent function checks whether the ClipboardItem functionality is available.

If it is, the addHtmlToClipboard function is run just as before. If it isn’t available, the new addTextToClipboard function is run instead.

This new addTextToClipboard takes the content to be copied, removes all traces of HTML code from it (via the sanitize function) and then writes it as text into the clipboard using navigator.clipboard.writeText.

From the callbacks, instead of console.logs, you could for example trigger a success notification or failure warning.

Try it out to see it working!

Top comments (0)