Reputation: 58662
I have a button
When I clicked on COPY
copyImageLinkText({ mouseenter, mouseleave }, e) {
this.showCopiedText = !this.showCopiedText
navigator.clipboard.writeText(this.imageLink)
clearTimeout(this._timerId)
mouseenter(e)
this._timerId = setTimeout(() => mouseleave(e), 1000)
},
This line seems to work perfectly locally on my MacBook Pro
navigator.clipboard.writeText(this.imageLink)
It's not working when I build and deployed it to my dev server.
TypeError: Cannot read properties of undefined (reading 'writeText')
Upvotes: 72
Views: 84143
Reputation: 461
The navigator.clipboard.writeText method should work in most modern browsers. However, if you're encountering a TypeError, it might be because the Clipboard API is not available in your environment. using document.execCommand('copy') for better compatibility:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Copy to Clipboard</title>
</head>
<body>
<textarea id="tocopy">This is some text to copy!</textarea>
<br>
<button onclick="copyToClipboard()">Copy Text</button>
<script>
function copyToClipboard() {
// Get the text field
var copyText = document.getElementById("tocopy");
// Select the text field
copyText.select();
copyText.setSelectionRange(0, 99999); // For mobile devices
// Copy the text inside the text field using the Clipboard API if available
if (navigator.clipboard) {
navigator.clipboard.writeText(copyText.value).then(() => {
alert("Copied the text: " + copyText.value);
}).catch(err => {
console.error('Failed to copy: ', err);
});
} else {
// Fallback method using document.execCommand('copy')
try {
document.execCommand('copy');
alert("Copied the text: " + copyText.value);
} catch (err) {
console.error('Fallback: Oops, unable to copy', err);
}
}
}
</script>
</body>
</html>
Upvotes: 0
Reputation: 385
It is better to use an async
and put your code in try catch
block.
async function copyCode() {
try {
await navigator.clipboard.writeText(this.input);
} catch (e) {
console.log(e);
}
}
Upvotes: 2
Reputation: 2713
Sorry for pasting a working code. I am using Jquery. you can do with JS only if you wish. It will not work until over https view..
$('.copy-email').click(function () {
var email = $(this).data('email');
writeClipboardText(email);
})
async function writeClipboardText(text) {
try {
await navigator.clipboard.writeText(text);
} catch (error) {
console.error(error.message);
}
}
Upvotes: 1
Reputation: 41
Some addition for the answer, that was useful for me, scroll with preventScroll
parameter as an argument for the scroll func, since the input will be removed, you probable won't need scroll to it
textArea.focus({preventScroll: true})
Upvotes: 3
Reputation: 7077
The use of navigator.clipboard
requires a secure origin. So if your dev environment is being served over HTTP, then the clipboard method won't be available.
According to MDN Clipboard
docs
This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.
Maybe you could check if this method is available with window.isSecureContext
, and disable the Copy Text button accordingly.
The best option is to use HTTPS in your dev environment.
But since you asked for a workaround, here's a (very hacky) working method. Using Document.exec
command, which is no longer recommended, in favour of ClipboardAPI
.
function unsecuredCopyToClipboard(text) {
const textArea = document.createElement("textarea");
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
} catch (err) {
console.error('Unable to copy to clipboard', err);
}
document.body.removeChild(textArea);
}
You can then just check if !navigator.clipboard
and call the fallback method, otherwise continue with the normal navigator.clipboard.writeText(...)
function. For example:
const unsecuredCopyToClipboard = (text) => { const textArea = document.createElement("textarea"); textArea.value=text; document.body.appendChild(textArea); textArea.focus();textArea.select(); try{document.execCommand('copy')}catch(err){console.error('Unable to copy to clipboard',err)}document.body.removeChild(textArea)};
/**
* Copies the text passed as param to the system clipboard
* Check if using HTTPS and navigator.clipboard is available
* Then uses standard clipboard API, otherwise uses fallback
*/
const copyToClipboard = (content) => {
if (window.isSecureContext && navigator.clipboard) {
navigator.clipboard.writeText(content);
} else {
unsecuredCopyToClipboard(content);
}
};
<button onClick="buttonPress()">➡️ Copy Message to Clipboard</button>
<script type="text/javascript"> const buttonPress = () => { copyToClipboard('Hello World!'); console.log('Clipboard updated 📥\nNow try pasting!'); }; </script>
Upvotes: 159