Let’s assume you’re building your own developer blog, and you’re going to have code snippets on your blog pages. In order to make the life of your readers easier, you decide to add a copy to the clipboard button to the code snippets, so readers can simply click the button to copy the code instead of having to manually select and CTRL + C.
Previously, document.execCommand.(“copy”) was used to achieve this purpose. But it is a very tacky solution and provides synchronous access to the clipboard, which has performance and security implications. So, the new clipboard API was designed to replace it.
The clipboard
API is accessed asynchronously can only be used on pages served over HTTPS and localhost
. The API can only be triggered by user interaction, such as a click, and requires the user to grant permission on the first instance of the call on a page. This is to prevent misuse and avoid potential issues.
The clipboard
API has 4 methods:
read
: used to get arbitrary data, such as images from the clipboard for pastingreadText
: used to get only textual components of the clipboard for pastingwrite
: used to copy arbitrary data, such as images, to the clipboard.writeText
: used to copy textual data to the clipboard
The clipboard API is straightforward in usage. However, at the time of writing this, it is not fully supported by all modern browsers. Firefox and IOS still have partial support, according to caniuse.
So, first, you need to check if the features and methods you want to use are supported by the receiving browser. For our use case, the method we need is writeText
.
Now, assuming that there will be a few code snippet boxes on each blog page, and they’ll all have the same class name and a similar HTML structure like so:
<div class="body">
<div class="box">
<p> Hello World !</p>
<button class="button">copy</button>
</div>
<div class="box">
<p> Lorem Ipsum!</p>
<button class="button">copy</button>
</div>
</div>
Then, the JavaScript will be:
const copyCode = async (event) => {
if (navigator.clipboard && navigator.clipboard.writeText) {
const code = event.target.parentElement.children[0].innerText;
try {
await navigator.clipboard.writeText(code)
event.target.textContent = 'Copied'
} catch (err) {
console.error('Failed to copy!', err)
}
}else{
//clipboard API or clipboard.writeText method is not supported
}
}
let buttons = document.querySelectorAll(".button");
buttons.forEach((button)=>{
button.addEventListener('click', async(e) => {
await copyCode(e)
})
})
The clipboard
methods returns promise hence the async
and await
keywords. We used event.target.parentElement.children[0]
, to select the first child element (which is the paragraph), of the parent element of the button on which the click event occurred.
If navigator.clipboard && navigator.clipboard.writeText
is not supported by the user’s browser, the code above will not run. In that case, you can either show an alert error within the else statement like; “Copy functionality not supported by your browser. Please copy manually”, or use the old document.execCommand
(which I wouldn’t advise).
For a full demo, see codepen here.
Blog Credits: Linda Ikechukwu
Comments are closed.