3

TL;DR

Is it possible to get the Clipboard API to write text from the result of an Axios get request in Safari even when the writeText() is a direct result of a user event?


Long version

I have an async button click event and inside of that click event I'm using Axios to fetch the HTML of another page. I want to take that string and save it to the clipboard using the Clipboard API.

This works in Chrome and Firefox but there are some issues in Safari I will show below.

Testing in:

  • Chrome 88.0.4324.192
  • Firefox 78.7.1
  • Safari 14.0.3

Closest SO issue I could find relating to this sort of thing is Javascript / Clipboard API / Safari iOS / NotAllowedError Message but I feel like my Clipboard API call is called directly within a user event.


Attempt 1 to get to work in Safari

copyButton.addEventListener('click', async (event) => {
  try {
    const {data: html} = await axios.get('https://website-to-copy.com');
    await navigator.clipboard.writeText(html);
    console.log('copy was a success');
  } catch (error) {
    console.log(error);
  }
});

Result 1 in Safari

  • Request is successfully made
  • Failure to write to clipboard
    • NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

My thoughts on Result 1

At the time I was thinking this would work. The writeText() call is a direct result of a user event and I'm just passing in a string... even though that string is a result of an Axios get request. When it didn't work I thought there must be something with the get request throwing off the permissions.


Attempt 2 to get to work in Safari

copyButton.addEventListener('click', async (event) => {
  try {
    const {data: html} = await axios.get('https://website-to-copy.com');
    // throw in a random string thinking maybe something
    // in the get request is throwing Clipboard API off
    await navigator.clipboard.writeText('some random text to copy');
    console.log('copy was a success');
  } catch (error) {
    console.log(error);
  }
});

Result 2 in Safari

  • Request is successfully made
  • Failure to write to clipboard
    • NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

My thoughts on Result 2

I was really surprised when my random text didn't copy. When attempt #1 failed I decided to leave the get request in but just feed writeText() some random text, not related to the get request in anyway, just to see if it would copy. Obviously the get request is still affecting the Clipboard API.


Attempt 3 to get to work in Safari

copyButton.addEventListener('click', async (event) => {
  try {
    // remove get request and see if i can get anything to
    // copy to clipboard
    //const {data: html} = await axios.get('https://website-to-copy.com');
    await navigator.clipboard.writeText('some random text to copy');
    console.log('copy was a success');
  } catch (error) {
    console.log(error);
  }
});

Result 3 in Safari

  • Text successfully copied to clipboard

My thoughts on Result 3

Well I'm happy that I can successfully copy text with the clipboard API in Safari. However I really would like to copy the result of the get request.

evans863
  • 63
  • 4
  • Did you ever have any luck with this? Facing the same issue. Works in other browsers, but not in Safari when it's after another `await`-ed statement. – jdlm Jan 13 '22 at 09:30
  • Safari does not allow data to be written to clipboard from result of async function – Hans Mar 13 '22 at 21:03

1 Answers1

0
copyButton.addEventListener('click', async (event) => {
    try {  
        const { ClipboardItem } = window;
        await navigator.clipboard.write([new ClipboardItem({ "text/plain": getUrl() })]).then(()=>console.log("copied"))
    } catch (error) {
        console.log(error);
    }
});
    
const getUrl = () => {
    const {data: html} = await axios.get('https://website-to-copy.com');
    return html;
}
Ethan McTague
  • 2,236
  • 3
  • 21
  • 53
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 31 '22 at 12:55
  • I get `Type 'string' is not assignable to type 'ClipboardItemData'` at "text/plain" – Chano Apr 07 '22 at 16:11
  • Are you using typescript in your project? – Mohkam Farid Apr 08 '22 at 09:06