Adding copy code button to Hugo blog
Explain how to add a copy code button on Hugo blog.
This article explains how to add a copy code button on Hugo blog.
The following lists are the table of contents about this article.
Target audience
- Those who want to add a copy code button to code block on Hugo blog.
Environment
- Hugo 0.57.2
- Hugo-extended 0.58.2
Preconditions
- Installed Hugo and Hugo-extended
Adding copy code button
Adding JavaScript code
Add the following code to static/js/add-on.js.
I use IIFE (Immediately Invoked Function Expression) because I want to narrow the scope of a variable.
(() => {
  'use strict';
  if(!document.queryCommandSupported('copy')) {
    return;
  }
  function flashCopyMessage(el, msg) {
    el.textContent = msg;
    setTimeout(() => {
      el.textContent = "Copy";
    }, 1000);
  }
  function selectText(node) {
    let selection = window.getSelection();
    let range = document.createRange();
    if (node.childElementCount === 2) {
      // Skip the title.
      range.selectNodeContents(node.children[1]);
    } else {
      range.selectNodeContents(node);
    }
    selection.removeAllRanges();
    selection.addRange(range);
    return selection;
  }
  function addCopyButton(containerEl) {
    let copyBtn = document.createElement("button");
    copyBtn.className = "highlight-copy-btn";
    copyBtn.textContent = "Copy";
    let codeEl = containerEl.firstElementChild;
    copyBtn.addEventListener('click', () => {
      try {
        let selection = selectText(codeEl);
        document.execCommand('copy');
        selection.removeAllRanges();
        flashCopyMessage(copyBtn, 'Copied!')
      } catch(e) {
        console && console.log(e);
        flashCopyMessage(copyBtn, 'Failed :\'(')
      }
    });
    containerEl.appendChild(copyBtn);
  }
  // Add copy button to code blocks
  let highlightBlocks = document.getElementsByClassName('highlight');
  Array.prototype.forEach.call(highlightBlocks, addCopyButton);
})();
Adding CSS code
Add the following code to static/css/add-on.css.
.highlight {
    position: relative;
}
.highlight pre {
    padding-right: 75px;
}
.highlight-copy-btn {
    position: absolute;
    bottom: 7px;
    right: 7px;
    border: 0;
    border-radius: 4px;
    padding: 1px;
    font-size: 0.7em;
    line-height: 1.8;
    color: #fff;
    background-color: #777;
    min-width: 55px;
    text-align: center;
}
.highlight-copy-btn:hover {
    background-color: #666;
}
That's it!
