How to add copy code button on Hugo sites

Guide to adding a copy code button to make your Hugo website user-friendly

The code is a tweak of the code given by Tom Spencer

Javascript

Create a js file where you will store all your Javascript, I am storing mine at /static/js/copy-code.js

This will control all your HTML elements as well as the “brain” behind the button

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
(function() {
    'use strict';
  
    if(!document.queryCommandSupported('copy')) {
      return;
    }
  
    function flashCopyMessage(el, msg) {
      el.textContent = msg;
      setTimeout(function() {
        el.textContent = "Copy";
      }, 1000);
    }
  
    function selectText(node) {
      var selection = window.getSelection();
      var range = document.createRange();
      range.selectNodeContents(node);
      selection.removeAllRanges();
      selection.addRange(range);
      return selection;
    }
  
    function addCopyButton(containerEl) {
      var copyBtn = document.createElement("button");
      copyBtn.className = "highlight-copy-btn";
      copyBtn.textContent = "Copy";
  
      var codeEl = containerEl.firstElementChild;
      copyBtn.addEventListener('click', function() {
        try {
          var 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
    var highlightBlocks = document.getElementsByClassName('highlight');
    Array.prototype.forEach.call(highlightBlocks, addCopyButton);
  })();

CSS

CSS is quite subjective but this can start as the starting point

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.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;
}

To actually show the button, you have to put the following code in post.html (displays the button in posts ONLY) or baseof.html (displays the button globally)

1
2
3
{{ if (findRE "pre.*?" .Content 1) }}
<script src="/js/copy-code.js"></script>
{{ end  }}

that’s it <3