JavaScript Clipboard API

In the previous lesson, we learned how to keep data for a single browser tab with session storage. Now let’s use the Clipboard API to copy text to and read text from the system clipboard.

📋 What is the Clipboard API?

The Clipboard API lets your page write text to the clipboard and read text back from it. It lives on the navigator.clipboard object that every modern browser provides.

The two methods you reach for most are listed below.

Method Meaning Returns
navigator.clipboard.writeText(text) Copies a string to the clipboard A promise
navigator.clipboard.readText() Reads the current clipboard text A promise that resolves to the text

Both methods return a promise, so you wait for them with await.

✍️ Copying Text with writeText()

navigator.clipboard.writeText() takes the string you want to copy and returns a promise. The promise resolves once the text is on the clipboard.

clipboard-api.js
async function copyText(text) {
await navigator.clipboard.writeText(text);
console.log("Text copied:", text);
}
copyText("Hello, clipboard!");

Let’s walk through what each line does:

  • async function copyText(text) declares a function marked async so we can await inside it; it accepts the string we want to copy.
  • await navigator.clipboard.writeText(text) sends the text to the clipboard and pauses the function until that promise resolves.
  • console.log("Text copied:", text) runs only after the copy finishes, confirming the text is now on the clipboard and ready to paste.
  • copyText("Hello, clipboard!") calls the function with a sample string to actually trigger the copy.

📥 Reading Text with readText()

navigator.clipboard.readText() returns a promise that resolves to whatever text is currently on the clipboard. Because it is a promise, you await the result.

clipboard-api.js
async function showClipboard() {
const text = await navigator.clipboard.readText();
console.log("Clipboard contains:", text);
}
showClipboard();

Here is what each line does:

  • async function showClipboard() declares an async function so we can await the read inside it.
  • const text = await navigator.clipboard.readText() reads the clipboard and waits for the promise, then stores the resolved string in text.
  • console.log("Clipboard contains:", text) prints whatever the clipboard held.
  • showClipboard() calls the function to run the read.

Reading the clipboard often asks the user for permission. The browser may show a prompt the first time your page tries to read it.

Tie back to async

writeText and readText both return promises, the same promises you learned about earlier. Mark your function async and await the call so the rest of your code runs only after the clipboard work is done.

🖱️ A Real Copy Button

Clipboard access must be triggered by a user action, such as a click. The example below wires a “Copy” button to copy a link and then shows a short “Copied!” message.

clipboard-api.js
const button = document.querySelector("#copyButton");
const link = "https://www.freecodingschool.com";
button.addEventListener("click", async () => {
try {
await navigator.clipboard.writeText(link);
button.textContent = "Copied!";
setTimeout(() => {
button.textContent = "Copy";
}, 2000);
} catch (error) {
button.textContent = "Failed to copy";
}
});

Let’s step through the key lines:

  • const button = document.querySelector("#copyButton") grabs the button element, and const link holds the text we want to copy.
  • button.addEventListener("click", async () => { runs the async handler on each click, which is the user action the browser requires.
  • await navigator.clipboard.writeText(link) copies the link and waits for the copy to finish.
  • button.textContent = "Copied!" updates the label once the copy succeeds, and the setTimeout resets it to Copy after two seconds.
  • catch (error) runs when the copy is blocked, showing Failed to copy instead.

🔒 Secure Context Required

The Clipboard API only works in a secure context. That means your page must be served over https, or run on localhost during development. On a plain http page, navigator.clipboard is undefined and the call fails.

Test on localhost

While you build, run your project on localhost, which counts as a secure context. When you deploy, serve the site over https so the clipboard keeps working.

⚠️ Common Mistakes to Avoid

Mistake Problem Solution
Calling it without a user action The browser blocks the copy because there was no click or tap Run it inside an event handler like click
Forgetting it returns a promise Your code continues before the text is actually copied Mark the function async and await the call
Expecting it to work on http navigator.clipboard is undefined outside a secure context Use https or localhost

Here is the difference in code:

clipboard-api.js
// ❌ Runs on page load with no user gesture
await navigator.clipboard.writeText("text"); // blocked by the browser
// ✅ Runs inside a click handler
button.addEventListener("click", async () => {
await navigator.clipboard.writeText("text"); // works
});

Let’s compare the two halves:

  • The first await navigator.clipboard.writeText("text") fires the moment the page loads, with no click behind it, so the browser blocks it.
  • The second call lives inside a click handler, so it runs as a direct response to the user’s click, and the browser allows the copy.

🔧 Try It Yourself!

  1. Add a button to a page and serve the page on localhost.
  2. In the button’s click handler, call await navigator.clipboard.writeText(...) to copy a link.
  3. Change the button text to Copied! after the copy succeeds, then reset it after two seconds.
  4. Add a readText() call to log the clipboard contents and confirm your text was copied.

🧩 What You’ve Learned

  • ✅ The Clipboard API lives on navigator.clipboard
  • writeText(text) copies text and readText() reads it back
  • ✅ Both methods return promises, so use async and await
  • ✅ Clipboard access must be triggered by a user action like a click
  • ✅ The API only works in a secure context (https or localhost)

🚀 What’s Next?

Now that you can copy and read clipboard text, we will learn how to find the user’s location in the browser. Let’s continue to Geolocation API.

Share & Connect