Published on: 31/03/2024
Written by James Bridge
This script goes through your page, and looks for all of the “<pre>” elemments. It then creates a div wrapper around each of these elements, and sets up a button to sit on the top right hand side.
It also configures a simple message to the user to confirm once code has been copied.
The styles are designed to work well with the basic astro md formatting that comes with tailwind prose class. If you are not using prose, or wish for a different color scheme then you may need to adjust the styles accordingly.
document.querySelectorAll("pre").forEach((pre) => {
// Create wrapper, button, and message elements
const wrapper = document.createElement("div");
const button = document.createElement("button");
const message = document.createElement("div");
// Set up the wrapper and button
wrapper.style.position = "relative";
button.textContent = "Copy Code";
button.style.position = "absolute";
button.style.top = "0";
button.style.right = "0";
button.style.background = "#FF6D2D";
button.style.color = "#2F2F2F";
button.style.padding = "5px 12px";
pre.style.paddingTop = "3.5rem";
pre.style.whiteSpace = "pre-wrap";
pre.style.wordBreak = "break-word";
// Set up the message
message.style.position = "absolute";
message.style.bottom = "20px";
message.style.right = "0";
message.style.background = "black";
message.style.color = "white";
message.style.padding = "5px";
message.style.borderRadius = "5px";
message.style.display = "none";
message.textContent = "Code Copied!";
// Add wrapper and button to the DOM
pre.parentNode?.insertBefore(wrapper, pre);
wrapper.appendChild(pre);
wrapper.appendChild(button);
wrapper.appendChild(message);
// Copy action
button.addEventListener("click", () => {
navigator.clipboard
.writeText(pre.textContent!)
.then(() => {
// Show message
message.style.display = "block";
// Hide message after 2 seconds
setTimeout(() => {
message.style.display = "none";
}, 2000);
})
.catch((err) => console.error("Error copying text: ", err));
});
});