Urgent.News

What's breaking now, across thousands of outlets.

Tech

The await That Silently Breaks navigator.clipboard.writeText()

Someone on your team ships a "Copy invite link" button. It fetches a fresh, single-use link from the API, then copies it to the clipboard so the user can paste it into Slack. Code review is clean. QA clicks it a dozen times. Works every time. Two weeks later, a support ticket: "I click Copy, I paste into Slack, and I get yesterday's clipboard contents. Not the link." Another ticket, same shape,…

A team adds a "Copy invite link" button to their software, which fetches a fresh single-use link from an API and copies it to the clipboard, allowing users to paste it into Slack. QA testing confirms the feature works flawlessly. However, two weeks later, support tickets begin pouring in, reporting that when users click the "Copy" button and paste the link into Slack, they receive yesterday's clipboard contents instead of the current link.

Despite extensive testing, the issue cannot be reproduced by developers who click the button multiple times. The problem is discovered when it is noted that all users affected had switched to another tab or clicked into another window within a few seconds after clicking the "Copy" button. The root cause is that the `navigator.clipboard.writeText()` method only runs if the document has focus and the user gesture is still active at the exact moment the method is called.

If any action interrupts this sequence, the method fails silently and returns a `NotAllowedError`. Developers tried various fixes, such as adding loading spinners, error handling, retrying the write operation, or using a `try/catch` block, but none of these solutions addressed the core issue. The real solution is to ensure the `navigator.clipboard.writeText()` call occurs immediately after the button click, before any other operations that could interrupt the sequence.

This can be achieved by using the `navigator.clipboard.write()` method, which accepts a `ClipboardItem` containing a promise that resolves to the URL. By handling the promise asynchronously, the `navigator.clipboard.write()` method ensures that the clipboard is filled in once the promise resolves, even if the document focus changes during the process.

It's important to note that this feature requires a secure context (HTTPS) and that `navigator.clipboard` is not supported on plain HTTP origins. Additionally, the deprecated `document.execCommand('copy')` method should not be used, as it is not guaranteed to work consistently across browsers. The key takeaway is to maintain synchronization between the clipboard operation and the user gesture, using promises to handle data that may not be immediately available.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

More from Thursday 3 September →