This sample code for copying plain text seems to work with most browsers…
navigator.clipboard.writeText(text).then(() => {
console.log("Copied.");
}).catch(err => {
console.log("Error.");
});
…whereas this sample code for copying HTML to the clipboard does NOT work with Mobile Chrome nor does it return an error…
navigator.permissions.query({name: "clipboard-write"}).then((result) => {
if (result.state === "granted" || result.state === "prompt") {
const blobInput = new Blob([exportContent], {type: "text/html"});
const clipboardItemInput = new ClipboardItem({"text/html" : blobInput});
navigator.clipboard.write([clipboardItemInput]).then(() => {
console.log("Copied");
}).catch(err => {
console.log("Error.");
});
}
else {
console.log("Permission denied.");
}
});
Is there another way to construct the second example to work in Android; and if not, how can I detect the failure given that navigator.clipboard.write
does not return an error in Mobile Chrome?
UPDATE: Better-Than-Nothing Workaround
Given that I'm not hopeful that this can be resolved without Google addressing the issue, I at least wanted to: (1) find a way to not have users blame my website/app for the Clipboard being empty; (2) not get on the slippery slope of trying to detect the devices that have the problem along with writing special case code; and (3) ensure that the process immediately starts working if Google ever gets around to fixing the problem. So…
Since I can successfully write plain text to the keyboard, I now have two parts to the code:
When writing the HTML works, the user doesn't see the message from Part 1 when pasting. When it doesn't work, the user sees the message and at least knows more about the problem and an alternative.
FINAL UPDATE
I have come to believe the HTML is on the Clipboard but not consistently accessible. That explains the reason for no errors being thrown. If I can get Gmail in Android to display a context menu, which it only does 20% of the time, I can successfully paste the HTML. GBoard never shows the HTML content but always shows the plain text.
I can live with the aforementioned workaround. It's a minor hassle for users the first time they encounter the issue, but after they realize their device has a problem, they just start using the alternative (which actually has some benefits).
I had this issue and I tried hard to solve it till I found that some mobile browsers just don't support it. So your first simple code is the best solution but instead of showing an error, I suggest you show a prompt telling the user to copy the given text in case the browser can't do it or doesn't support it.
function copyText() {
navigator.clipboard.writeText(text).then(() => {
alert("text is copied to clipboard");
}, () => {
window.prompt("Please copy this text", text);
});
}
Edit: regarding your comment, for that you can just put the prompt block in try and catch:
function copyText() {
navigator.clipboard.writeText(text).then(() => {
alert("text is copied to clipboard");
}, () => {
try {
window.prompt("Please copy this text", text);
} catch (error) {
alert("Your browser doesn't support this function");
}
});
}