I got interested in the clipboard after reading a blog recently about certain publications limiting peoples ability to copy content and replacing it with links to purchase the articles and/or sharing rights to the article. The author was perturbed enough to de-minify the code and look at what they were doing. It turned out that they were making use of the browsers clipboard API to do this injection.
I also remembered reading/hearing about some mobile apps creeping on your clipboard to read it without your knowledge. One of those was TikTok and maybe that's par for the course with them but the other was LinkedIn. Is it possible that there are website's out there creeping on my clipboard as I move around the internet? So I figured I'd have a bit of a look at the Clipboard APIs and see what could be done with it.
API Overview
Clipboard API is an experimental API that exists to replace Document.execCommand
There are three parts to the API
navigator.clipboard
An object that provides methods to interact with the clipboard. It exists on window.navigator.clipboard
.
It provides four asynchronous methods:
read
readText
write
writeText
ClipboardItem
A class for interacting with the read
and write
methods of Clipboard using Blob
objects to represent binary data. This allows images and other non text data to be added to the clipboard.
ClipboardEvent
DOM events that fire on cut
, copy
, and paste
clipboard interactions.
Sample Code
I've put together a sample application making use of these different events. The only dependency is http-serve
so that the code can be served on localhost.
Clipboard manipulation
Adding and reading from the clipboard are single line calls.
Adding to the clipboard
To add text to the clipboard it's a mater of calling the writeText
method on the clipboard.
await navigator.clipboard.writeText(text);
Adding image data to the clipboard is a little more complex. In this case I have borrowed heavily from the MDN article on ClipboardItem
.
The code brings in an image via the fetch
API. Reads the response as a Blob
object. Uses that blob to create a ClipboardItem
passing the blob in as part of an options object with the property name determined by the blobs type. This ClipboardItem
instance is then written to the clipboard.
const imgURL = "/copy.png";
// fetch the image
const data = await fetch(imgURL);
// read the response as a Blob;
const blob = await data.blob();
// Add the blob to the clipboard
await navigator.clipboard.write([
new ClipboardItem({
[blob.type]: blob,
}),
]);
Reading
Reading from the clipboard is another one line call. Note that the user will need to allow access to the clipboard to read the contents.
const clipboardData = await navigator.clipboard.readText();
All I've done with the data is to write it out to the console. I couldn't think of a good reason why a web page should be reading the clipboard rather than interacting with the paste
event.
Event handling
To demonstrate working with clipboard events handlers are registered for each of the cut
, copy
and paste
events.
document.body.addEventListener("cut", handleCut);
document.body.addEventListener("copy", handleCopy);
document.body.addEventListener("paste", handlePaste);
For cut and copy the functions take the data selected in the document and modify the content before adding it to the clipboard with:
await navigator.clipboard.writeText(text);
I couldn't think of anything The paste event sets the background colour of the paste target element.
Issues
It's still experimental and I've fund that it's stable but that not all the features are implemented as expected. In particular events don't include clipboard data. The cut
, copy
, and paste
events should include a clipboardData
property that contains the data affected by the user-initiated cut, copy, or paste operation, along with its MIME type. My experience is that this DataTransfer Object is unpopulated.
I tested my sample application in Brave (which is a Chromium based browser) and Firefox on Windows.
Brave
Using Version 1.11.97 C hromium: 84.0.4147.89 (Official Build) (64-bit)
Other than the unpopulated clipboardData
property everything seems to be working as I would expect.
Firefox
Using 78.0.2 (64-bit) on Windows
There were a couple of inconsistencies in the way I would expect the APIs to behave in Firefox
I was able to write to the clipboard on cut and copy events but was unable to get the selected data from text boxes or text areas. I was able to get the data selected within <p>
elements.
Reading from the clipboard appears not to be implemented when calling navigator.clipboard.readText
I had the following error thrown navigator.clipboard.readText is not a function
.
Conclusion
I'm yet to work out what a good and genuine reason for using the clipboard API's. like a lot of things in software development it's a tool that is good to have available and is going to be useful for a specific problems and pretty useless for the rest of the time. There is no need to go looking to find nails to hit with the clipboard API hammer just because you want to use it.
Thankfully it looks like Firefox and Chrome (Brave) have my back as far as stopping webpages from creeping on me.
Top comments (0)