Jekyll: Copy code to clipboard


This post goes over how to add a “Copy” code to clipboard button to a Jekyll site. It’s inspired by the functionality on Docusaurus and GitHub.

Copy button

Code blocks rendered by the rouge highlighter have the highlight class on the <pre> element:

var codeBlocks = document.querySelectorAll('pre.highlight');

Create the copy button element:

var copyButton = document.createElement('button');
copyButton.type = 'button';
copyButton.ariaLabel = 'Copy code to clipboard';
copyButton.innerText = 'Copy';

Append it to the code block:

codeBlock.append(copyButton);

The button shouldn’t show by default:

pre.highlight > button {
  opacity: 0;
}

On code block hover, show the button:

pre.highlight:hover > button {
  opacity: 1;
}

On button active or focus, show it:

pre.highlight > button:active,
pre.highlight > button:focus {
  opacity: 1;
}

On click, copy the code to the clipboard:

codeBlocks.forEach(function (codeBlock) {
  // ...
  copyButton.addEventListener('click', function () {
    var code = codeBlock.querySelector('code').innerText.trim();
    window.navigator.clipboard.writeText(code);
  });
});

Provide feedback when it’s copied:

copyButton.innerText = 'Copied';
var fourSeconds = 4000;

setTimeout(function () {
  copyButton.innerText = 'Copy';
}, fourSeconds);

Code

Include the JavaScript in _layouts/post.html.

// assets/js/post.js
var codeBlocks = document.querySelectorAll('pre.highlight');

codeBlocks.forEach(function (codeBlock) {
  var copyButton = document.createElement('button');
  copyButton.className = 'copy';
  copyButton.type = 'button';
  copyButton.ariaLabel = 'Copy code to clipboard';
  copyButton.innerText = 'Copy';

  codeBlock.append(copyButton);

  copyButton.addEventListener('click', function () {
    var code = codeBlock.querySelector('code').innerText.trim();
    window.navigator.clipboard.writeText(code);

    copyButton.innerText = 'Copied';
    var fourSeconds = 4000;

    setTimeout(function () {
      copyButton.innerText = 'Copy';
    }, fourSeconds);
  });
});

Import the Sass in assets/css/style.scss:

/* _sass/_post.css */
pre.highlight > button {
  opacity: 0;
}

pre.highlight:hover > button {
  opacity: 1;
}

pre.highlight > button:active,
pre.highlight > button:focus {
  opacity: 1;
}

Check out the code example.



Please support this site and join our Discord!