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;
}
}