How to make copy buttons for code elements in 2024

Javascript

Copy buttons in pre-code elements are very useful features. If you don't need to support old deprecated browsers, I'll show you here how to make them in 2024. And of course this code works with highlight.js.

code-copy-buttons

You need javascript

async function writeClipboardText(text) {
    try {
        await navigator.clipboard.writeText(text);
    } catch (error) {
        console.error(error.message);
    }
}


document.addEventListener('DOMContentLoaded', function(event) {
    document.querySelectorAll("pre code").forEach(function(codeElement) {
        const preElement = codeElement.closest("pre");
        const tpl = document.createElement("div");
        tpl.innerHTML = '<button type="button" class="code-copy button is-small">Copy</button>';
        const button = tpl.firstChild;
        button.addEventListener("click", function () {
            this.innerText = 'Copying..';
            writeClipboardText(this.closest("pre").querySelector("code").textContent).then(function() {
                button.innerText = 'Copied!';
            }).catch(function() {
                button.innerText = 'Error!';
            }).finally(function() {
                setTimeout(function () {
                    button.innerText = 'Copy';
                }, 1000)
            });
        });
        preElement.append(button);
        preElement.classList.add("has-copy-button");
    });
});

And some css to improve it a little bit

Since I use bulma css framework, I don't need to style the buttons much.

pre.has-copy-button {
  position: relative;
}

pre.has-copy-button .code-copy {
  position: absolute;
  top: 10px;
  right: 10px;
  display: none;
}

pre.has-copy-button:hover .code-copy {
  display: inline-block;
}

@media screen and (max-width: 1023px) {
  pre.has-copy-button .code-copy {
    display: inline-block;
  }
}