I am trying to run a WebApp which allows files sharing. After few google search, I found Web Share API like the standard to do so. According to the documentation it should works like this using plain JS
This is the code for html page
<p><button>Share MDN!</button></p>
<p class="result"></p>
The code to share all sort "textbased" metadata:
let shareData = {
title: 'MDN',
text: 'Learn web development on MDN!',
url: 'https://developer.mozilla.org',
}
const resultPara = document.querySelector('.result');
if (!navigator.canShare) {
resultPara.textContent = 'navigator.canShare() not supported.';
}
else if (navigator.canShare(shareData)) {
resultPara.textContent = 'navigator.canShare() supported. We can use navigator.share() to send the data.';
} else {
resultPara.textContent = 'Specified data cannot be shared.';
}
The code above works fine, the trouble happens when I try to share files.
According to the documentation it should works like this:
// filesArray is an array of files we want to share (audios, images, videos, pdf)
if (navigator.canShare && navigator.canShare({ files: filesArray })) {
navigator.share({
files: filesArray,
title: 'Pictures',
text: 'Our Pictures.',
})
.then(() => console.log('Share was successful.'))
.catch((error) => console.log('Sharing failed', error));
} else {
console.log(`Your system doesn't support sharing files.`);
}
I started my code from this example and I never success to share a file. My actual code using React and Typescript looks like this:
//some react code here
const shareNow = async () => {
let imageResponse = await window.fetch('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', {mode: "no-cors"});
let imageBuffer = await imageResponse.arrayBuffer();
let fileArray = [new File([imageBuffer], "File Name", {
type: "image/png",
lastModified: Date.now()
})];
if (navigator.canShare && navigator.canShare({ files: filesArray })) {
navigator.share({
files: filesArray
}).then(() => {
console.log('Thanks for sharing!');
})
.catch(console.error);
}
}
//some react code here too
At this point, my typescript compiler yell at me. Apparently, the navigator object has no method canShare()
I am new to typescript, but I don't understand how and why the navigator could have less attribute since TypeScript is JavaScript superset.
Anyone has an idea on how to solve that except running normal JS ?
Thank you for your time reading this, and I hope to thank you for your answers.
P.S: I also tried a react-component based solution, but all the component I found in open source which wraps Web Share API does not allow file sharing.
Edit
Hey, @DenverCoder9
There is the same use case but using vanilla JS, could anyone try it and tell me what I am doing wrong please ?
<html>
<head>
<title>Sharing Image</title>
<meta charset="UTF-8" />
</head>
<body>
<div className="App">
<img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"/>
<button id="button">Share</button>
</div>
</body>
<script>
async function shareImage(title, imageUrl) {
const image = await fetch(imageUrl, {mode: "no-cors"});
const blob = await image.blob();
const file = new File([blob], title, { type: 'image/png' });
const filesArray = [file];
const shareData = {
files : filesArray
}
// add it to the shareData
const navigator = window.navigator
const canShare = navigator.canShare && navigator.canShare(shareData) //navigator.canShare()navigator.share //navigator.canShare()
if(canShare){
navigator.share(shareData)
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
}
else {
console.log("cannot share this file in this context")
}
}
document.getElementById('button').onclick = function() {
shareImage("Title", "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png")
};
</script>
</html>
I am running this on safari for mac