Skip to content

Instantly share code, notes, and snippets.

@cferdinandi
Created May 28, 2025 16:59
Show Gist options
  • Save cferdinandi/444158d5921a81a22527c13e001b9d1b to your computer and use it in GitHub Desktop.
Save cferdinandi/444158d5921a81a22527c13e001b9d1b to your computer and use it in GitHub Desktop.
Watch the tutorial: https://youtu.be/1WFM4j1Q2wE
/**
* Don't show button until JavaScript is instantiated
*/
share-me:not(:defined) {
display: none;
}
/**
* Visually hide an element, but leave it available for screen readers
* @link https://github.com/h5bp/html5-boilerplate/blob/master/dist/css/main.css
* @link http://snook.ca/archives/html_and_css/hiding-content-for-accessibility
*/
share-me [role="status"] {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
white-space: nowrap;
width: 1px;
}
customElements.define('share-me', class extends HTMLElement {
/**
* The class constructor object
*/
constructor () {
// Gives element access to the parent class properties
super();
// Get the button
this.btn = this.querySelector('button');
if (!this.btn) return;
// If API not supported, hide and bail
if (!navigator.share) {
this.setAttribute('hidden');
return;
}
// Share settings
this.title = this.getAttribute('title');
this.url = this.getAttribute('url');
this.text = this.getAttribute('text');
// Success settings
this.originalBtn = this.btn.innerHTML;
this.successBtn = this.getAttribute('on-success-btn') ?? 'Shared!';
this.successSR = this.getAttribute('on-success-sr') ?? this.successBtn;
// Duration time settings
let durationTime = parseFloat(this.getAttribute('success-duration'));
this.duration = Number.isNaN(durationTime) ? 5000 : durationTime;
// Add an ARIA live region
this.notify = document.createElement('div');
this.notify.setAttribute('role', 'status');
this.append(this.notify);
// Listen for events
this.btn.addEventListener('click', this);
}
/**
* Handle events on the Web Component
*/
handleEvent () {
this.triggerShare();
}
/**
* Trigger the share card
*/
async triggerShare () {
let { title, url, text } = this;
try {
// Open the share card
await navigator.share({ title, url, text });
// Show success message
this.btn.innerHTML = this.successBtn;
this.notify.textContent = this.successSR;
// Revert to original
setTimeout(() => {
this.btn.innerHTML = this.originalBtn;
this.notify.textContent = '';
}, this.duration);
} catch (error) {
console.warn('Unable to share.', error);
}
}
});
<!DOCTYPE html>
<html>
<head>
<title>Share Web Component</title>
<style type="text/css">
body {
margin: 1em auto;
max-width: 30em;
width: 88%;
}
</style>
<link rel="stylesheet" type="text/css" href="./share-wc.css">
</head>
<body>
<h1>Share API</h1>
<!--
Options & Settings
1. Details about what's being shared ✓
2. Button text on success ✓
3. Screen reader text on success ✓
4. Duration before removing text ✓
-->
<share-me
title="GMT Membership"
url="https://members.gomakethings.com"
text="Join today!"
on-success-btn="Shared!"
on-success-sr="Shared the link"
success-duration="3000"
>
<button aria-label="Share a link to GoMakeThings.com">Share This</button>
</share-me>
<script src="./share-wc.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment