Async Clipboard API has some security considerations. From the doc:
Chromium browsers:
- Reading requires the Permissions API clipboard-read permission be granted.
- Writing requires either the clipboard-read permission or transient activation.
Firefox & Safari:
- The clipboard-read and clipboard-write permissions are not supported (and not planned to be supported) by Firefox or Safari.
Is it needed to query permissions or is it safe to use the clipboard API directly for all supported browsers? Was it different in the past? Is it going to change?
It seemed to me, that the correct way would be to query permissions first (at least, for Chromium-based browsers). Then, if permissions are granted, use the clipboard API. That is:
navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
if (result.state === "granted") {
navigator.clipboard.readText().then((text) => console.log(text));
});
In practice, when I use the clipboard API directly, without querying permissions, it still works in supported browsers. The Chromium-based browsers show a permission popup on the first usage.
navigator.clipboard.readText().then((text) => console.log(text));
Full example:
<html>
<body>
<input id="b1" type="button" value="click" />
</body>
<script>
document.querySelector("#b1").addEventListener('click', (e) => {
navigator.clipboard.readText().then(
(clipText) => console.log(clipText));
});
</script>
</html>
Using the clipboard API
might throw an error (Read permission denied) if the clipboard access was blocked by the client. To handle such scenerio, the easiest way is to use a try-catch block. Here is an implementation:
<input id="b1" type="button" value="click" />
<script>
document.querySelector("#b1").addEventListener('click', async () => {
try {
const text = await navigator.clipboard.readText();
alert('Text from clipboard: ' + text);
} catch (err) {
console.error('Operation failed', err);
}
});
</script>
Also, there is no longer any need for having any permission-checks as try-catch handles any permission-denied error.