One line of JavaScript for a real share sheet
Most "share" buttons on the web are a row of brand icons that each open a popup to some intent URL. Fine, but it's a lot of markup for something the operating system already does better. Bilal Hussain reminded me how little it takes to do it properly with the Web Share API.
The one line
navigator.share takes a title, some text, and a URL, and hands them to the OS.
The OS opens its real share sheet, the same one your native apps use, and the
user picks Messages, AirDrop, WhatsApp, whatever:
await navigator.share({
title: "A great article",
text: "You should read this",
url: "https://example.com/post",
});It returns a promise that resolves when the share completes and rejects if the
user backs out, so wrap it in a try/catch and don't treat a cancel as an
error. On a phone it looks like this:
The catch, and the fallback
Web Share is everywhere on mobile, in Safari, and in Chrome, but not in every desktop browser. So feature-detect it and only call it when it's there:
if (navigator.share) {
try { await navigator.share(data); return; } catch {}
}
// otherwise: open a copy-link + social menuWhen it's missing, fall back to the old approach: a small menu with copy-link and the usual intent URLs (X, LinkedIn, Facebook, WhatsApp, email). Same button, works everywhere, and on the platforms that matter most it's a single native call.
One more thing worth knowing: navigator.share only runs from a user gesture
(a real click) and on a secure origin (HTTPS), so you can't fire it on load.
There's also navigator.canShare(...) if you want to check whether specific
data, including files, is shareable before showing the button.
Inspired by Bilal Hussain. Grab the component on the Share Button page.
Ask your agent to implement this
Read the full writeup at https://seangeng.com/writing/the-web-share-api.md and implement it in my project.
It covers: One line of JavaScript for a real share sheet — The Web Share API hands a title, text, and URL to the operating system and opens the same native share sheet every app uses. Here's a share button that uses it, with a graceful fallback for desktop.
Requirements:
- Follow the technique/approach exactly as described in the writeup.
- Adapt names, colors, and styling to my project's existing conventions.
- If it's a component, make it reusable with sensible props and TypeScript types.
- Keep it accessible: semantic HTML, keyboard support, and respect prefers-reduced-motion.
- When done, tell me which files you created or changed and how to use it.Paste into Claude Code, Codex, Cursor, or any agent. view raw .md download source .zip