Skip to content

Manifest · Manifest member

share_target manifest member

Published

Limited availabilityNot supported in Firefox (Desktop), Safari (iOS), Safari (macOS)WICG draft

share_target registers an installed web app as a destination in the operating system’s share sheet. When the user picks the app, the browser delivers the shared title, text, URL, and files to a URL inside the app’s scope, either as query parameters on a GET navigation or as a multipart/form-data POST that a service worker can intercept.

Chrome 76 on Android, Edge 89 on desktop (GET, with limited file support), and Samsung Internet 12.0 read the member (BCD html.manifest.share_target). Safari 27 on iOS and macOS and Firefox 157 do not implement it, so the app never appears in their share sheets. The member is the receiving half of sharing; the sending half is navigator.share().

Flow diagram of a share target: the manifest declares share_target with action, method, enctype and params; after the app is installed the OS share sheet lists it. When the user picks it the browser either navigates to the action URL with title, text and url as query parameters (GET), or submits multipart/form-data that the service worker fetch handler reads with formData(), stores, and answers with a 303 redirect (POST). Both paths end on a page showing the shared content.
Share target: from the manifest declaration through the OS share sheet to the GET or POST handler.
  • Type: object with action (in-scope URL that receives the share), method ("GET" or "POST"), enctype ("application/x-www-form-urlencoded" or "multipart/form-data"), and params, an object mapping the shared fields to parameter names: title, text, url, and files, an array of { "name", "accept" } where accept lists MIME types or extensions.
  • Default: absent, so the app is not a share target. Inside the object method defaults to "GET" and enctype to "application/x-www-form-urlencoded".
  • Example value: { "action": "/share", "method": "GET", "params": { "title": "title", "text": "text", "url": "url" } }.

Chromium validates the combination and drops the whole member on a bad one, logging to the manifest’s error list: invalid method. Allowed methods are: GET and POST., invalid enctype for GET method. Only application/x-www-form-urlencoded is supported., files are only supported with multipart/form-data POST., and property 'share_target' ignored. Property 'action' is invalid. when action is cross-origin or outside scope. Files therefore require "method": "POST" with "enctype": "multipart/form-data"; text-only targets work with the defaults.

The app must be installed before it appears in the share sheet, and the entry carries the manifest’s short_name and icon. Android shows it alongside native apps; a user who has not installed the PWA has no way to share into it, which is why a share-target page also needs an ordinary route for pasted content. When the shared payload has a text but no url, Chrome on Android often places the link inside text, so handlers parse both fields.

The examples follow the two delivery paths and then cover the user who cannot reach either.

Section titled “Receiving a link and text with a GET navigation”

A read-later app accepts the three text fields. The share opens /share?title=…&text=…&url=… in the installed app, and the page reads the query string on load. Because Android sometimes delivers the link in text, the handler falls back to the first URL it finds there.

{
"share_target": {
"action": "/share",
"method": "GET",
"params": { "title": "title", "text": "text", "url": "url" }
}
}
const params = new URLSearchParams(location.search);
const text = params.get('text') ?? '';
const url = params.get('url') ?? text.match(/https?:\/\/\S+/)?.[0] ?? null;
if (url) {
saveLink({ title: params.get('title') ?? '', url });
} else {
showPasteForm(text); // nothing shareable arrived: let the user paste a link instead
}

Use history.replaceState after saving so a reload does not store the same link twice.

Receiving files through the service worker

Section titled “Receiving files through the service worker”

Images need POST and multipart encoding. The service worker intercepts the POST to action, reads the form data, stores the files, and answers with a 303 redirect so the client lands on a normal GET page; without the redirect a reload would resubmit the share.

{
"share_target": {
"action": "/share/upload",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "title",
"files": [{ "name": "photos", "accept": ["image/jpeg", "image/png", "image/webp"] }]
}
}
}
service-worker.js
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (event.request.method !== 'POST' || url.pathname !== '/share/upload') return;
event.respondWith((async () => {
const form = await event.request.formData();
const files = form.getAll('photos');
const cache = await caches.open('shared-inbox');
await Promise.all(files.map((file, i) => cache.put(`/shared/${Date.now()}-${i}`, new Response(file))));
return Response.redirect('/share/review', 303);
})());
});

The /share/review page lists caches.open('shared-inbox') and lets the user confirm before the files go to the server, which also covers a share that arrives while the device is offline.

Falling back when the app is not installed

Section titled “Falling back when the app is not installed”

The share sheet only lists installed apps, and Safari 27 and Firefox 157 list no web apps at all. A route that accepts pasted content and, where navigator.share exists, offers the outgoing direction keeps the feature usable everywhere.

const canReceive = matchMedia('(display-mode: standalone)').matches; // installed: the OS can share into us
const canSend = 'share' in navigator;
document.querySelector('#hint').textContent = canReceive
? 'Share from any app and pick this one.'
: canSend
? 'Install the app to receive shares; you can still share out with the button.'
: 'Paste a link or text in the box.';

display-mode: standalone is a proxy for “installed”, not a guarantee that the share target was registered; it is the best signal a page has.

Specifications

SpecificationStatus
manifest: share_targetWICG draft
Web Share Target APIW3C draft
  • Legend
  • Yes
  • Partial
  • Flag
  • No
  • Unknown
Browser / PlatformSupportVersionsConfidenceSourceNotes
Chrome (Android)Yes76lowsource—
Edge (Desktop)Yes89lowsource1
Samsung InternetYes12.0lowsource—
Firefox (Desktop)No—lowsource2
Safari (iOS)No—lowsource3
Safari (macOS)No—lowsource4
  1. Limited file support in GET mode.
  2. No desktop install path consuming share_target.
  3. Not supported on iOS.
  4. Not supported on macOS.

Source data: /compatibility/manifest-share-target.json · Global usage: 72 % (StatCounter 2026-05)

Source: spec · MDN · Last verified 2026-07-11 · Confidence: low (computed from sources)