Copying to the Clipboard in 2025


Copy-to-clipboard helpers feel almost primitive today, yet they still pop up in projects every week. The gist you shared shows the classic pattern that dominated for years:
// Legacy helper
function copyToClipboard(text) {
const el = document.createElement('textarea');
el.value = text; // put text in a hidden <textarea>
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
el.select(); // select its content
document.execCommand('copy'); // 👉 tries to copy
document.body.removeChild(el); // tidy up
}
It works (even in quirky WebViews and IE 11), but it comes with warts:
Uses
document.execCommand('copy')
, now deprecated and removable at any moment.Can scroll the page or open the mobile keyboard because focus jumps to the hidden element.
Fails inside Shadow DOM or sandboxed iframes.
Meet navigator.clipboard
All evergreen browsers now support a much cleaner, promise-based API:
async function copy(text) {
await navigator.clipboard.writeText(text);
console.log('Copied ✔');
}
Why it’s better
execCommand() hack | navigator.clipboard | |
Requires HTTPS | ❌ | ✅ (secure context) |
Returns a Promise | ❌ (sync) | ✅ |
Reads and writes | ❌ (write-only) | ✅ readText() / read() |
Handles images & blobs | ❌ | ✅ |
Permission control | Minimal | Granular, auditable |
A Future-Proof Helper
The safest approach is a tiny feature-test wrapper:
export async function copyText(text) {
if (navigator.clipboard?.writeText) {
return navigator.clipboard.writeText(text); // modern path
}
// fallback for legacy browsers
const el = document.createElement('textarea');
el.value = text;
el.style.position = 'fixed'; // avoid scrolling jump
el.style.opacity = '0';
document.body.appendChild(el);
el.focus();
el.select();
document.execCommand('copy');
document.body.removeChild(el);
}
Best Practices
Call in response to a user gesture (click, key press). Browsers block clipboard writes otherwise.
Gracefully handle rejections. the user may deny permission or the OS clipboard could be unavailable.
Don’t UA-sniff. Feature-test (
navigator.clipboard?.writeText
) and fallback when missing.
Takeaway
By 2025, the Clipboard API should be your default. Keep the legacy shim for those edge-case WebViews, but stop sprinkling hidden <textarea>
elements around your app. Cleaner code, happier users, and one less deprecated API to worry about.
Subscribe to my newsletter
Read articles from Amir Yurista directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
