diff --git a/_includes/head.html b/_includes/head.html
index fbbf96e7c9..3fb4bd12ac 100644
--- a/_includes/head.html
+++ b/_includes/head.html
@@ -68,6 +68,7 @@
+
{%- endif -%}
{%- if site.local_search -%}
diff --git a/_scss/_content.scss b/_scss/_content.scss
index 0d95b07e0e..f76f338f40 100755
--- a/_scss/_content.scss
+++ b/_scss/_content.scss
@@ -46,6 +46,15 @@ code {
.highlighter-rouge {
margin: 15px 0;
+ position: relative;
+
+ button.copy {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ background: none;
+ border: none;
+ }
}
/*
diff --git a/assets/js/copy.js b/assets/js/copy.js
new file mode 100644
index 0000000000..70c71076fc
--- /dev/null
+++ b/assets/js/copy.js
@@ -0,0 +1,29 @@
+// copy code icon markup
+const copyIcon = ``
+
+// insert copy buttons for code blocks
+const codeBlocks = document.querySelectorAll("div.highlighter-rouge")
+codeBlocks.forEach((codeBlock) => {
+ codeBlock.insertAdjacentHTML(
+ "afterbegin",
+ ``
+ )
+})
+
+// handler that saves the code block innerText to clipboard
+function copyCodeBlock(event) {
+ const copyButton = event.currentTarget
+ const codeBlock = copyButton.parentElement.querySelector("pre.highlight code")
+ const code = codeBlock.innerText.trim()
+ window.navigator.clipboard.writeText(code)
+
+ // change the button text temporarily
+ copyButton.textContent = "Copied!"
+ setTimeout(() => copyButton.innerHTML = copyIcon, 3000)
+}
+
+// register event listeners for copy buttons
+const copyButtons = document.querySelectorAll("button.copy")
+copyButtons.forEach((btn) => {
+ btn.addEventListener("click", copyCodeBlock)
+})