Adding a Copy Button to Code Blocks in Hugo with Netlify
Introduction
Adding a “Copy Code” button to code blocks in your Hugo blog can significantly enhance the user experience, especially for technical blogs. With the help of GitHub Copilot, I implemented a solution to add a copy button above code blocks, styled similarly to GitHub’s copy button.
This blog post walks you through the steps to achieve this functionality using JavaScript and CSS. By the end, you’ll have a fully functional “Copy” button that appears in the top of your code blocks.
Steps to Add the Copy Button
1. Create the JavaScript File
First, create a JavaScript file named copy-code.js
in your Hugo site’s static/js
folder. This script will handle the creation of the “Copy” button and its functionality.
Here’s the code for copy-code.js
:
document.addEventListener("DOMContentLoaded", function () {
const codeBlocks = document.querySelectorAll("pre");
codeBlocks.forEach((block) => {
// Create a wrapper for the code block and button
const wrapper = document.createElement("div");
wrapper.className = "code-block-wrapper";
block.parentNode.insertBefore(wrapper, block);
wrapper.appendChild(block);
// Create a copy button
const button = document.createElement("button");
button.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 21H9c-1.1 0-2-.9-2-2V7c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2zm0-2V7H9v12h10zM5 17H3V5c0-1.1.9-2 2-2h10v2H5v12z"/>
</svg>`;
button.className = "copy-code-button";
// Add click event to copy code
button.addEventListener("click", () => {
const code = block.querySelector("code").innerText;
navigator.clipboard.writeText(code).then(() => {
button.innerHTML = "Copied!";
setTimeout(() => {
button.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 24 24">
<path d="M19 21H9c-1.1 0-2-.9-2-2V7c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2zm0-2V7H9v12h10zM5 17H3V5c0-1.1.9-2 2-2h10v2H5v12z"/>
</svg>`;
}, 2000);
});
});
// Prepend the button to the wrapper
wrapper.insertBefore(button, block);
});
});
This script dynamically adds a “Copy” button to each code block (
element) on the page. When clicked, the button copies the code inside the block to the clipboard and temporarily changes its text to “Copied!”.2. Include the JavaScript in Your Layout
To ensure the script is loaded on all pages, add a reference to it in your
single.html
layout file. Place the following line before the closing</body>
tag:<!-- filepath: \Hugo\sites\M365Blog\layouts\_default\single.html --> <script src="/js/copy-code.js" defer></script>
This ensures the script is loaded after the page content, allowing it to attach the “Copy” functionality to the code blocks.
3. Add CSS for Button Positioning
Next, style the “Copy” button to position it in the top-right corner of the code block. Add the following CSS to your custom.css file:
/* filepath: \Hugo\sites\M365Blog\static\css\custom.css */ /* Wrapper styling for code blocks */ .code-block-wrapper { position: relative; margin-bottom: 1rem; padding-top: 1.5rem; /* Add space for the button */ } /* Copy button styling */ .copy-code-button { position: absolute; top: 5px; /* Position the button at the top */ right: 10px; /* Position the button to the right */ background-color: transparent; border: none; cursor: pointer; padding: 5px; font-size: 16px; color: #6a737d; /* GitHub-style gray */ } .copy-code-button:hover { color: #0366d6; /* GitHub-style blue */ } .copy-code-button svg { vertical-align: middle; }
CSS for Button Positioning
Wrapper Styling
- The
.code-block-wrapper
is set toposition: relative
to allow the button to be positioned absolutely within it. padding-top: 1.5rem
ensures there is enough space above the code block for the button.
Button Positioning
- The
.copy-code-button
is positioned absolutely (position: absolute
) relative to the.code-block-wrapper
. top: 5px
andright: 10px
place the button in the top-right corner of the code block.
Hover Effect
- The button changes color to blue (
#0366d6
) when hovered, mimicking GitHub’s style.
Amend the single.html
to Add Reference to the Custom JavaScript
To ensure the custom JavaScript file is loaded on all pages, add a reference to it in your single.html
layout file. Place the following line before the closing </body>
tag:
<script src="/js/copy-code.js" defer></script>
Result
The “Copy” button will now appear in the top of the code block, with a small margin separating it from the code.