Skip to content

Web Share API: native share sheet from the browser

In one line: navigator.share() invokes the platform’s native share sheet — the same OS-level dialog the user gets from a native app — letting them send a URL, title, text, or files to any app installed on their device without you building your own share UI.

navigator.share() accepts a single options object with any combination of:

  • url — absolute URL (the page itself is the common default).
  • title — optional hint; the receiving app often ignores it.
  • text — free-form text alongside or instead of a URL.
  • files — an array of File objects (images, audio, video, text files, PDFs). File sharing requires the canShare({ files }) check first (see below).
// Guard with feature detection, then share
async function share() {
if (!navigator.share) {
// Fallback: copy URL to clipboard
await navigator.clipboard.writeText(location.href);
return;
}
try {
await navigator.share({
title: document.title,
url: location.href,
});
} catch (err) {
if (err.name !== 'AbortError') throw err; // user cancelled — not an error
}
}

navigator.share() must be called from a user activation (click, keypress, or similar transient event). Calling it from a timer, DOMContentLoaded, or any async context that has lost the activation throws a NotAllowedError. This is a browser security invariant defined in the spec.

The Web Share API is only available in secure contexts — HTTPS or localhost. On plain HTTP the API is undefined regardless of browser.

Not every platform or browser supports every file type. Before passing files, check:

const supported = navigator.canShare?.({ files: myFiles });
if (supported) {
await navigator.share({ files: myFiles, title: 'Photos' });
} else {
// provide alternative: download link, copy URL, etc.
}

navigator.canShare() returns false (rather than throwing) when sharing the given data is not possible — for example, when a file type is not on the browser’s allow-list or when file sharing is unsupported entirely.

A PWA can also receive shares from other apps by declaring a share_target in its manifest. This is a separate mechanism — see the Manifest share_target reference for details. The Web Share API (this page) covers the sending side only.

See /compatibility/ for current per-browser data.

Decision question Recommended action Rationale
Want to offer sharing on all platforms? Call navigator.share() only after a user gesture; provide a clipboard fallback when undefined. The API is not universal; a graceful fallback keeps the feature accessible.
Sharing files, not just URLs? Check navigator.canShare({ files }) before calling share. File-sharing support varies by browser and platform.
Also want to receive shares from other apps? Add a share_target to your manifest. Web Share Target is a separate mechanism from the sending API.
Need analytics on share events? Resolve the navigator.share() promise, then record. The promise resolves after the user acts; a rejection with AbortError means they cancelled.
  • Gate the call behind if (navigator.share) and provide a fallback (clipboard or custom UI).
  • Call navigator.share() only inside a user-gesture event handler.
  • Serve the page over HTTPS — the API is unavailable on plain HTTP.
  • Catch AbortError silently; only surface other errors to users.
  • Use navigator.canShare({ files }) before sharing files.
  • Do not rely on the title field being displayed — receiving apps handle it inconsistently.