Using JavaScript to copy text to the clipboard

Providing users of a web application with a way of copying data to the system clipboard is a common requirement that can be achieved by employing some client-side JavaScript. This functionality is often needed so that users can copy some form of text, for example, a quotation or a block of code, without needing to manually select and copy the text manually.

As with any web application, you’ll need to consider what the browser support is for the APIs that you are working with. Ideally, you’ll write your code in such a way that it will work with as many browser versions as possible to maximise compatibility.

In this post, I will show you how to copy text to the clipboard using JavaScript in a way that is compatible with almost any browser in use today. I’ll also demonstrate alternative code that uses newer JavaScript features and therefore will only work in recent versions of modern browsers.

Code samples

Let’s dive straight in and see how we can implement the copy-to-clipboard functionality within a web application.

Maximum compatibility

We’re going to start with some code that aims to support as many browsers as possible.

The code below documents a copyTextToClipboard JavaScript function that should work in practically every browser that is still in use today. It’s hard to make guarantees, but the code should offer a very good level of support across as many browser versions as possible.

/**
 * Copies the specified text to the clipboard.
 * @param {String} text The text to copy.
 */
 function copyTextToClipboard(text) {
    if (navigator.clipboard) {
        // Modern versions of Chromium browsers, Firefox, etc.
        navigator.clipboard.writeText(text).then(function() {
            alert(‘Text successfully copied to clipboard!’);
        }, function(error) {
            alert(‘Failed to copy text to clipboard: ‘ + error.message);
        });
    }
    else if (window.clipboardData) {
        // Internet Explorer.
        window.clipboardData.setData(‘Text’, text);
        alert(‘Text successfully copied to clipboard!’);
    }
    else {
        // Fallback method using Textarea.
        var textArea            = document.createElement(‘textarea’);
        textArea.value          = text;
        textArea.style.position = ‘fixed’;
        textArea.style.top      = ‘-999999px’;
        textArea.style.left     = ‘-999999px’;
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            var successful = document.execCommand(‘copy’);

            if (successful) {
                alert(‘Text successfully copied to clipboard!’);
            }
            else {
                alert(‘Could not copy text to clipboard’);
            }
        } catch (error) {
            alert(‘Failed to copy text to clipboard: ‘ + error.message);
        }

        document.body.removeChild(textArea);
    }
};

Let’s break down the above code into a manageable set of chunks, tackling each of the three main conditional sections within the function in the following sub-sections.

Note that depending on your scenario, the alert function calls may not be what you want. You may choose to remove these or replace them with console.log function calls instead.

Clipboard API

The copyTextToClipboard function first of all checks if the browser that is running the code has support for the Clipboard API by testing if navigator.clipboard is ‘truthy‘.

The Clipboard API is supported by most modern browsers. This includes Chrome and Firefox since 2018, as well as Edge and Safari since 2020. At the time of writing, CanIUse indicates that 94.18% of users can use the Clipboard API features.

Note that the Clipboard API is only available over HTTPS, non-secure pages will need to fall back to one of the alternative methods covered in the sub-sections that follow.

The writeText function is used to write the specified text to the clipboard. The writeText function is asynchronous and returns a Promise object once the contents of the clipboard have been updated. The promise will be rejected if the specified text cannot be written to the clipboard for any reason.

Note that it is also possible to wait for the result of the writeText function asynchronously via the await keyword. This is demonstrated later in the post.

Clipboard Data

If the Clipboard API is not available, the code tests if Clipboard Data can be accessed instead.

clipboardData can only be accessed directly on the window object by Internet Explorer.

The setData function is used to write text data to the clipboard by specifying the type of data as ‘Text’. The setData function is synchronous and will therefore return after the contents of the clipboard have been updated.

Note that Internet Explorer was retired on 15th June 2022 and can no longer be accessed directly on modern Windows operating systems that have recent Windows Updates installed. You may still find that users on older, unsupported operating systems such as Windows XP and Windows 7 may still be running Internet Explorer.

Copy command

As a fallback position, if neither the Clipboard API nor Clipboard Data are supported, the code will fall back to using document.execCommand to execute the ‘copy’ command, copying text from an off-screen Textarea.

Note that document.execCommand is a deprecated function, but it remains a well-supported feature across a wide range of browsers at the time of writing and is a good fallback position.

The Textarea style is updated to have a ‘fixed’ position with the top and left coordinates set to large minus values such that the Textarea will appear offscreen and therefore should not be visible to the user.

The textarea element is then temporarily added to the DOM body using the appendChild function and the Textarea is focused and selected so that its contents can be copied.

A try...catch statement wraps the next section of code where the document.execCommand function is called to execute the ‘copy’ command. The document.execCommand function returns a Boolean object to indicate if the command was successful or not. Any exceptions that may be thrown will be caught by the catch block.

Lastly, the temporary textarea element is removed from the DOM body using the removeChild function. This action is done outside of a finally block to maximise browser compatibility.

Usage

It is most common for a copy-to-clipboard function to be triggered intentionally by the user through clicking a button on the user interface. It’s usually not a good idea to overwrite the user’s clipboard without their consent as there may be something important on their clipboard that they don’t want to lose!

The HTML below demonstrates how the copyTextToClipboard function can be triggered when a button is clicked by a user.

<button onclick=copyTextToClipboard(‘Hi, from the clipboard button!’)”>Copy to Clipboard</button>

If this is the first time that the web application has attempted to copy data to the clipboard and the Clipboard API is being used, the user will see a prompt requesting if they want to grant the application access to the clipboard. An example of this prompt is shown below.

Clipboard access prompt
Clipboard access prompt

The user must press the ‘Allow’ button in order for the Clipboard API code to work.

Note that is also possible to check for and request the appropriate permission by using navigator.permissions to work with the Permissions API.

Modern browsers

If you only plan to support modern browsers, you may choose to simplify the code by working solely with the Clipboard API. This could make sense when you are developing a web application where you have a lot of control over the browsers and associated browser versions that your users are using, or for cases where the copy-to-clipboard functionality is more of a ‘nice to have’ and it isn’t essential that the feature is available.

Below is a simplified example of how to copy text to the clipboard asynchronously via the Clipboard API.

const Clipboard = () => {
    const copyText = async (text) => {
        try {
            await navigator.clipboard.writeText(text);
            alert(‘Text successfully copied to clipboard!’);
        } catch (error) {
            alert(`Failed to copy text to clipboard: ${error.message}`);
        }
    };

    return {
        copyText
    };
};

The above code is using modern JavaScript (ES6) features such as async functions and template literals.

Additionally, the above code is using the Module Pattern to keep the copyText function out of the global scope.

Below is an example of how to use the copyText function.

const clipboard = Clipboard();
clipboard.copyText(‘Hi, from the sample script!’);

As mentioned earlier in this post, there may be changes that you will want to make to the code depending on your specific scenario, such as removing the alert function calls and/or adding logging, for example.

Summary

In this post, I covered how you can use JavaScript to copy text to the system clipboard.

I started by providing a code sample that aims to support the broadest possible range of browsers by using specific clipboard APIs when they are available and falling back to other methods that should work for older browser versions.

I also demonstrated how you would implement the code if supporting older browsers isn’t a concern for your application and you want to work with the latest JavaScript features instead.


I hope you enjoyed this post! Comments are always welcome and I respond to all questions.

If you like my content and it helped you out, please check out the button below 🙂

Comments