Four years ago, I read the article Does Anyone Use Social Sharing Buttons on Mobile?
The result was shocking: Only 0.2% of users ever click on a mobile sharing button! Yet, most clients I've worked for, insist on having sharing buttons on almost all pages.
But, here's the thing: Users like being in control. Maybe they don't like Twitter or Facebook, but prefers Instagram, Slack or Teams — or something else entirely.
Why not give them control, and let them decide themselves which platform to share to?
This is where the navigator.share api comes in handy. It will use the native sharing of the user's device.
Browser support isn't that great on desktop devices, but on mobile devices, the support is OK:
Let's write our own little "Sharing component", that can use regular, link-based sharing, if native sharing is not supported.
First, the markup:
<div
data-share="device facebook twitter linkedin"
data-share-label="Share on"
data-share-device="Share using device sharing">
</div>
This tells the script that we want to use device-sharing (aka native sharing), but it should fallback to link to Facebook, Twitter and LinkedIn, if native sharing is not supported.
The data-share-label
will be added as an aria-label
to all fallback-links, while the data-share-device
will be added to the icon for native sharing.
This is how it looks like on a device supporting native sharing:
And this is how it looks like if it doesn't:
JavaScript:
export function Share(element) {
const canShare = 'share' in window.navigator;
const options = element.dataset.share.split(' ');
const shareIndex = options.findIndex(option => { return option === 'device' });
const shareData = {
facebook: { url: 'https://www.facebook.com/share.php?u=' },
linkedin: { url: 'https://www.linkedin.com/shareArticle?mini=true&url' },
twitter: { url: 'https://www.twitter.com/share?url=' }
}
if (shareIndex > -1 && !canShare) {
options.splice(shareIndex, 1);
}
if (shareIndex > -1 && canShare) {
const shareButton = h('button', {
'aria-label': `${element.dataset.shareDevice}`,
'data-share-item': ''
}, [h('i')]);
shareButton.addEventListener('click', () => {
navigator.share({
title: document.title,
url: location.href
}).catch(() => { return });
})
element.appendChild(shareButton);
}
else {
options.forEach(option => {
const shareLink = h('a', {
'aria-label': `${element.dataset.shareLabel} ${option}`,
'data-share-item': option,
href: shareData[option].url + encodeURIComponent(location.href),
rel: 'noopener noreferrer',
target: '_blank'
}, [h('i')])
element.appendChild(shareLink);
})
}
}
A small helper-function is required:
function h(type, attributes, children = []) {
const element = document.createElement(type);
for (let key in attributes) {
element.setAttribute(key, attributes[key]);
}
if (children.length) {
children.forEach(child => {
if (typeof child === 'string') {
element.appendChild(document.createTextNode(child));
} else {
element.appendChild(child);
}
});
}
return element;
}
And finally, to init the share-component/s:
const shares = document.querySelectorAll(`[data-share]`);
shares.forEach(element => {
Share(element);
});
Codepen Demo
If your browser supports navigator.share
, (for instance Safari on both Mac/iOS) you'll see the single share-icon below, otherwise the fallback with three icons:
Thanks for reading!
Top comments (0)