javascriptsharenavigator

navigator.share() throw DOMException: Permission denied even on mobile


I have a NextJS app that fetches an API and receives a blob image.

Everything works correctly and I can see the image on the browser with the <img src="blob:https://myurl.com/blob-id">

I would like to create a button that share the image on Instagram story. I'm using the navigator.share() API like

async function shareImage(imgLink: string, bindata: string) {
    console.log(`clicked shareImageAsset: ${imgLink}`);

    const binaryData = Buffer.from(JSON.parse(bindata));
    const blobImage = new Blob(
      [binaryData.buffer],
      { type: "image/jpeg" } /* (1) */
    );

    const fileName = imgLink.split("/").pop();
    const fileNameTrue: string = fileName ? fileName : "image.jpg";
    const filesArray = [
      new File([blobImage], fileNameTrue, {
        type: "image/jpeg",
        lastModified: Date.now(),
      }),
    ];
    console.log(filesArray);
    const shareData = {
      title: fileNameTrue,
      files: filesArray,
      url: document.location.origin,
    };
    if (navigator.canShare && navigator.canShare(shareData)) {
      await navigator.share(shareData);
    }
    // TODO implements a fallback to download the file
  }

but when the code executes the last line, await navigator.share(shareData); I got the error navigator.share DOMException: Permission denied even if I use it on mobile, with a smartphone with the Instagram app and a user logged in

EDIT

I've also added in next.config.js

const nextConfig = {
  async headers() {
    return [
      {
        source: "/",
        headers: [
          {
            key: "Permissions-Policy",
            value: "web-share=(*)",
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;

with no luck


Solution

  • In the end the issue was just I was passing the filename without the extension.

    Fixed adding .jpg at the end of the blob URL

    const fileName = imgLink.split("/").pop();
    const fileNameTrue: string = fileName ? fileName : "image";
    const filesArray = [
      new File([blobImage], fileNameTrue + ".jpg", {
        type: "image/jpeg",
        lastModified: Date.now(),
      }),