How to create a copy code block button

How to create a copy code block button

In this tutorial I will show you how to add a working copy button to every code block on your page.


Intro

This tutorial was based on SPDUK Steve’s great article with a little twist that the copy button is hidden by default, and only reveals when the user hovers over the code block. The text of the button also changes to “Copied” when it is clicked.


Html

Create a basic code block:

<pre>
<code>
function(){
    console.log('lala');
}
</code>
</pre>

Javascript

This code will create a copy button inside each pre elements, and makes it copy the contens to the clipboard, once the button is clicked. The code is well commented thanks to Steve, so you can see what’s happening through the process. Add the following code to your script file:

// get the list of all highlight code blocks
const highlights = document.querySelectorAll("pre");

highlights.forEach((pre) => {
    // create the copy button
    const copy = document.createElement("button");
    copy.innerHTML = "Copy";
    // add the event listener to each click
    copy.addEventListener("click", handleCopyClick);
    // append the copy button to each code block
    pre.append(copy);
});

const copyToClipboard = (str) => {
    const el = document.createElement("textarea"); // Create a <textarea> element
    el.value = str; // Set its value to the string that you want copied
    el.setAttribute("readonly", ""); // Make it readonly to be tamper-proof
    el.style.position = "absolute";
    el.style.left = "-9999px"; // Move outside the screen to make it invisible
    document.body.appendChild(el); // Append the <textarea> element to the HTML document
    const selected =
        document.getSelection().rangeCount > 0 // Check if there is any content selected previously
            ? document.getSelection().getRangeAt(0) // Store selection if found
            : false; // Mark as false to know no selection existed before
    el.select(); // Select the <textarea> content
    document.execCommand("copy"); // Copy - only works as a result of a user action (e.g. click events)
    document.body.removeChild(el); // Remove the <textarea> element
    if (selected) {
        // If a selection existed before copying
        document.getSelection().removeAllRanges(); // Unselect everything on the HTML document
        document.getSelection().addRange(selected); // Restore the original selection
    }
};

function handleCopyClick(evt) {
    // get the children of the parent element
    const { children } = evt.target.parentElement;
    // grab the first element (we append the copy button on afterwards, so the first will be the code element)
    // destructure the innerText from the code block
    const { innerText } = Array.from(children)[0];
    // copy all of the code to the clipboard
    copyToClipboard(innerText);
    // Change the button's text to "Copied"
    this.textContent = "Copied";
    // Change back the button text to "Copy" after 2 sec
    setTimeout(() => {
        this.textContent = "Copy";
    }, 2000);
}

Css

The following code adds a little styling to the copy button and makes it invisible to reveal when the code block is hovered with the mouse. Add these styles to your css file:

pre button {
    position: absolute;
    right: 5px;
    top: 5px;
    border: 0;
    background: #e7e7e7;
    padding: 3px 6px;
    border-radius: 3px;
    font-size: 13px;
    color: #666;
    opacity: 0;
    cursor: pointer;
}

pre button:hover {
    background: #d5dae2;
    color: black;
    transition: background-color 0.2s;
}

pre:hover button {
    opacity: 1;
    transition: opacity 0.3s;
}

Add Comment

Comment submitted

Thanks! Your comment will appear shortly. Please reload the page.


Tags