Web Share
navigator.share() triggers the native OS share sheet with one call -- title, text, URL, and files. Web Share Target flips the direction: your PWA becomes a target in other apps' share sheets.
Every app on iOS and Android has a share button. Tap it and a sheet slides up with every app that can receive that content -- messages, mail, social apps, notes. You can add your PWA to that list.
Two APIs, two directions. Web Share lets your site share outward. Web Share Target lets your PWA receive shares inward.
navigator.share()
One call, the native share sheet appears:
shareButton.addEventListener('click', async () => {
await navigator.share({
title: 'Bolognese Recipe',
text: 'The best pasta sauce I have ever made.',
url: 'https://recipes.example/bolognese',
})
})title, text, and url are all optional -- but at least one must be present. The OS decides how to use each field in the share UI. Some apps display the title, some the URL, some both.
The call must come from a user gesture. A button click, a touch event. Calling navigator.share() on page load throws.
Sharing Files
Pass a files array of File objects to share images, documents, or any binary:
const response = await fetch('/recipe.pdf')
const blob = await response.blob()
const file = new File([blob], 'recipe.pdf', { type: 'application/pdf' })
if (navigator.canShare({ files: [file] })) {
await navigator.share({ files: [file], title: 'Recipe PDF' })
}navigator.canShare() validates the data before you call share. Always check it when sharing files -- not all targets can receive every file type, and calling share() with unsupported data throws.
// Simple URL share without file check
if ('share' in navigator) {
// Web Share is available
}Support: Green tier -- Safari, Chrome, Edge, Firefox (except Firefox desktop). Works on iOS, Android, and desktop in Chromium.
Web Share Target
The inbound direction. Your PWA registers itself in the manifest to appear in other apps' share sheets.
{
"share_target": {
"action": "/receive-share",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "title",
"text": "text",
"url": "url",
"files": [
{
"name": "media",
"accept": ["image/png", "image/jpeg", "image/webp"]
}
]
}
}
}When the user shares content to your PWA from another app, the browser launches your app and posts a multipart/form-data request to /receive-share. The params field maps the OS share fields to the form field names you expect.
Read the share in JavaScript on the receiving page:
// On /receive-share, the service worker intercepts and passes to the page:
self.addEventListener('fetch', event => {
const url = new URL(event.request.url)
if (url.pathname === '/receive-share' && event.request.method === 'POST') {
event.respondWith(
event.request.formData().then(data => {
const title = data.get('title')
const text = data.get('text')
const files = data.getAll('media') // matches the "name" in share_target
// handle the incoming share
return Response.redirect('/', 303)
})
)
}
}) ExpandWeb Share: navigator.share() to OS share sheet, and Web Share Target receiving shares from other apps
Practical Uses
Recipe app: Every recipe page has a share button that opens the native sheet. Users share to messages, notes, WhatsApp. No custom share UI needed.
Image editor PWA: Registers as a Web Share Target for image/*. Users take a photo in the camera app, tap share, and the editor opens with the image loaded.
Coupon or unlock flow: A marketing email contains a link like myapp://unlock?code=XXXX. In combination with Protocol Handlers, clicking that link in a mail app opens the PWA directly to the unlock flow.
Support
Web Share (navigator.share) is green tier -- broadly supported across Safari, Chrome, and Edge on mobile and desktop. Web Share Target (receiving shares via manifest) is Chromium-only and requires an installed PWA.
The next set of APIs in this chapter covers three browser capabilities that each reach a different part of the OS: contact access, fullscreen control, and native payment UI. Contact Picker, Fullscreen, and Payment Request next.
The Essentials
navigator.share({ title, text, url, files })-- triggers native OS share sheet. Must be called from a user gesture.navigator.canShare(data)-- validates data before callingshare(). Required check when sharing files.- Web Share Target registers your PWA in other apps' share sheets via
"share_target"in the manifest. You receive the share as a POST to theactionURL. - Web Share (
navigator.share) is green tier -- iOS, Android, desktop Chromium. Web Share Target is Chromium-only, installed PWA only. - File sharing requires an array of
Fileobjects and acanSharecheck -- not all targets accept all file types.
Further Reading and Watching
- Web Share API Tutorial - Native Sharing is Easy! (YouTube) -- covers
navigator.share(),canShare()for file validation, and the Web Share Target manifest setup - Integrate with the OS sharing UI with the Web Share API -- web.dev -- official guide with file sharing, canShare checks, and the full Web Share Target manifest spec
Keep reading