Clipboard API used in conjunction with Axios in click event

973 views Asked by At

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.

1

There are 1 answers

3
Mohkam Farid On
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;
}