How to Copy Text to the Clipboard with JavaScript using the Clipboard API

Video thumbnail

Copying text to the clipboard from a web page may seem like a basic thing, but behind it lies a modern API and a series of important security considerations. In this guide, I'll show you how to implement this functionality in JavaScript, with real examples, cross-browser compatibility, and some tricks I learned while applying it to my own projects.

When we copy something from an application or a website, we are modifying our operating system's clipboard. And here comes a very important point: we are accessing the operating system using JavaScript.

I show you how you can modify the clipboard, that is, how to implement the copy and paste functionality using JavaScript.

What does copying to the clipboard in JavaScript mean?

When we copy something—be it text, a link, or a code snippet—we are modifying the operating system's clipboard. This involves a small "conversation" between the browser and the OS, something that JavaScript can do using the Clipboard API.

In my case, the first time I needed this functionality was to allow users to copy code snippets with a click. For this, document.execCommand('copy') is used, since that method is obsolete. The modern and safer solution is navigator.clipboard.writeText().

Using navigator.clipboard.writeText

The Clipboard API offers a simple and secure way to copy text to the clipboard. The navigator.clipboard.writeText() method receives the text you want to copy and returns a promise because it is an asynchronous operation that directly interacts with the operating system.

navigator.clipboard.writeText("Tu texto aquí");

This method receives the text you want to copy, and since it is an operation that interacts with the operating system (something that could be busy or require permissions), it works as a promise.

Why is it a promise?

Every time we access the disk or the operating system from JavaScript, a promise is used because those operations are not resolved immediately.

That's why here we are also using a promise, which resolves when the text has been successfully copied to the clipboard. If you want to do something once it has been copied, you can use .then(), just as I do, where I show a small toast to notify the user that the action is complete:

  btn.addEventListener('click', () => {
    this.$toast.success(this.$t('resource.copied') + "!");
    const text = pre.innerText;
    navigator.clipboard.writeText(text).then(() => {
      // btn.innerText = this.$t('resource.copied');
      this.$toast.success(this.$t('resource.copied') + "!");
    }).catch(err => {
      console.error('Error al copiar: ', err);
    });
  });

Security considerations: HTTPS and browser permissions

A couple of things you should keep in mind:

  • You must be on **HTTPS** for this to work correctly. For example, if you work on localhost with HTTPS (like https://localhost), you won't have problems.
  • However, if you are in an **insecure environment**, such as a virtual host with http (without the "s"), you will see an error like the one I show on the screen:
    • navigator.clipboard is null
  • This happens because browsers block access to the clipboard in insecure environments. In my case, the first time I tested it in a local environment with HTTP, the method simply didn't respond. When activating HTTPS, everything worked correctly.

Browser compatibility

If you're worried that the user's browser is old or doesn't support this API, you can do a simple validation like this:

if (navigator.clipboard) {
   // puedes usar clipboard.writeText
} else {
   // muestra un mensaje alternativo
}

With this, you can copy and paste content easily using JavaScript and offer a better user experience, as long as you respect the security requirements.

Improving the user experience (UX)

Beyond it working, it's important that the user knows the text was copied correctly. You can show a message, change the button's text, or launch a small toast.

Another improvement is using **async/await**, which makes the code cleaner:

async function copiarTexto() {
 try {
   await navigator.clipboard.writeText("Texto copiado con éxito");
   alert("Texto copiado al portapapeles ✅");
 } catch (err) {
   console.error("No se pudo copiar:", err);
 }
}

You can also copy automatically when the page loads or on a double-click, although this should be done with caution, as some browsers block it if there's no direct user interaction.

Common errors and how to solve them

Error    Probable Cause    Solution
navigator.clipboard is undefined    Page without HTTPS or insecure context    Use HTTPS or localhost environment
Promise rejected    Permission denied or browser block    Retry after user interaction
Nothing is copied    Code executed outside of a user event    Execute inside a click or input

In my experience, the most common error is executing the function before the user interacts. For security, most browsers don't allow copying without explicit action.

Frequently Asked Questions (FAQ)

  • Why doesn't navigator.clipboard work on HTTP?
    • Because browsers only enable the Clipboard API on HTTPS sites or on localhost.
  • Which browsers support clipboard.writeText()?
    • Most modern browsers, except Internet Explorer.
  • How can I show a message when the text is copied?
    • You can use alert(), a toast, or change the button's text after copying.
  • What's the difference between execCommand('copy') and clipboard.writeText()?
    • execCommand is an old and less reliable API; clipboard.writeText is the modern and secure method.

Conclusion

Copying text to the clipboard with JavaScript is a small but powerful functionality. By using navigator.clipboard.writeText(), you can offer a smooth, secure, and modern experience.

In my case, applying this technique in my projects significantly improved user interaction; on the Academia website, I implemented it so the user can copy codes with a single click.

I agree to receive announcements of interest about this Blog.

How to use `navigator.clipboard.writeText()` to copy text to the clipboard in JavaScript. Learn best practices, common mistakes, and browser support.

| 👤 Andrés Cruz

🇪🇸 En español