Copy with the Clipboard API
async function copy(text) {
await navigator.clipboard.writeText(text);
console.log("Copied!");
}
copy("hello world");
Because it is promise-based, awaiting the call tells you exactly when the text has landed on the clipboard.
Wire it to a copy button
button.addEventListener("click", async () => {
await navigator.clipboard.writeText(input.value);
button.textContent = "Copied!";
});
This reads the value from an input and gives the user instant feedback by changing the button label.
Handle failures gracefully
try {
await navigator.clipboard.writeText(text);
} catch (err) {
console.error("Copy failed", err);
}
Copying can fail if the page is not served over HTTPS or the user denied permission, so always wrap it in try/catch.
Read text back from the clipboard
const text = await navigator.clipboard.readText();
console.log(text);
Common mistakes
- Calling it outside a user gesture. The copy must run from a click or similar event.
- Expecting it to work on plain HTTP. The Clipboard API needs a secure (HTTPS) context.
- Ignoring the promise. Await it so you know it succeeded.
Frequently asked questions
Why does writeText do nothing?
The Clipboard API only works in a secure context and usually requires a user gesture like a click. On localhost and HTTPS it works; on plain HTTP it is blocked.
Is execCommand still needed?
Rarely. document.execCommand("copy") is deprecated. Use it only as a fallback for very old browsers, with the Clipboard API as the primary path.
Practice browser APIs in our free JavaScript course.