navigator.clipboard is undefined

Google ChromeClipboard

Google Chrome Problem Overview


Why is navigator.clipboard always undefined in the following snippet?

var clipboard = navigator.clipboard;
if (clipboard == undefined) {
	console.log('clipboard is undefined');
} else {
	clipboard.writeText('stuff to write').then(function() {
		console.log('Copied to clipboard successfully!');
	}, function() {
		console.error('Unable to write to clipboard. :-(');
	});
}

More on the clipboard API can be found here.

Chrome Version: 68.0.3440.106.

I'm sure this was working at some point, but no longer is. It's confusing because this table suggests that the Clipboard API is implemented in Chrome (has been for some time), but this table of specific API methods suggests that none of the methods of the API is supported??

Google Chrome Solutions


Solution 1 - Google Chrome

This requires a secure origin — either HTTPS or localhost (or disabled by running Chrome with a flag). Just like for ServiceWorker, this state is indicated by the presence or absence of the property on the navigator object.

https://developers.google.com/web/updates/2018/03/clipboardapi

This is noted in the spec with [SecureContext] on the interface: https://w3c.github.io/clipboard-apis/#dom-navigator-clipboard

You can check the state of window.isSecureContext to learn if that's the reason a feature is unavailable. Secure contexts | MDN

And yes, you should set up HSTS to make sure HTTP redirects to HTTPS.

Solution 2 - Google Chrome

you can write an all-in-one wrapper function.

  • if in secure context (https) : use navigator clipboard api
  • if not : use the 'out of viewport hidden text area' trick
// return a promise
function copyToClipboard(textToCopy) {
    // navigator clipboard api needs a secure context (https)
    if (navigator.clipboard && window.isSecureContext) {
        // navigator clipboard api method'
        return navigator.clipboard.writeText(textToCopy);
    } else {
        // text area method
        let textArea = document.createElement("textarea");
        textArea.value = textToCopy;
        // make the textarea out of viewport
        textArea.style.position = "fixed";
        textArea.style.left = "-999999px";
        textArea.style.top = "-999999px";
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();
        return new Promise((res, rej) => {
            // here the magic happens
            document.execCommand('copy') ? res() : rej();
            textArea.remove();
        });
    }
}

use :

copyToClipboard("I'm going to the clipboard !")
    .then(() => console.log('text copied !'))
    .catch(() => console.log('error'));

ps : do not try it in a repl like jsfiddle/copeden/...

Solution 3 - Google Chrome

Try this:

if (typeof (navigator.clipboard) == 'undefined') {
    console.log('navigator.clipboard');
    var textArea = document.createElement("textarea");
    textArea.value = linkToGo;
    textArea.style.position = "fixed";  //avoid scrolling to bottom
    document.body.appendChild(textArea);
    textArea.focus();
    textArea.select();

    try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        toastr.info(msg);
    } catch (err) {
        toastr.warning('Was not possible to copy te text: ', err);
    }

    document.body.removeChild(textArea)
    return;
}
navigator.clipboard.writeText(linkToGo).then(function () {
    toastr.info(`successful!`);
}, function (err) {
    toastr.warning('unsuccessful!', err);
});

Solution 4 - Google Chrome

A minimal solution for copying tooltips when HTTPS is not yet available and the solution with document.execCommand('copy') does not work. But it requires that the user selects and copies by hand what is displayed in the alert.

function copyToClipboard(text) {
  if(navigator.clipboard) {
    navigator.clipboard.writeText(text);
  }
  else{
    alert(text);
  }
}

Solution 5 - Google Chrome

This solutions works at the moment (it includes cross browser support, error handling + clean up).

https://stackoverflow.com/a/33928558/318380

Solution 6 - Google Chrome

In localhost, the clipboard is blocked by the chrome browser. You check this by going to the following path

Chrome > settings > privacy and Security > site settings > View permissions and data stored across sites then click on your localhost URL which will mentation on the page and check the permission of the clipboard

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondrmrbrewerView Question on Stackoverflow
Solution 1 - Google ChromeJosh LeeView Answer on Stackoverflow
Solution 2 - Google ChromeSimon DehautView Answer on Stackoverflow
Solution 3 - Google ChromeJuliano CostaView Answer on Stackoverflow
Solution 4 - Google ChromeLaurent LyaudetView Answer on Stackoverflow
Solution 5 - Google ChromejazkatView Answer on Stackoverflow
Solution 6 - Google ChromeRamkrishna BhattView Answer on Stackoverflow