Badging and Share Target
App Badging API
Section titled “App Badging API”The App Badging API lets an installed PWA display a small badge on its icon in the OS taskbar, dock, or home screen. This is the same unread-count dot you see on native messaging apps.
Setting and clearing a badge
Section titled “Setting and clearing a badge”// Show a numeric badgeasync function setBadge(count) { if ('setAppBadge' in navigator) { await navigator.setAppBadge(count); }}
// Show a plain dot (no number)async function setDotBadge() { if ('setAppBadge' in navigator) { await navigator.setAppBadge(); }}
// Clear the badgeasync function clearBadge() { if ('clearAppBadge' in navigator) { await navigator.clearAppBadge(); }}Always feature-detect with 'setAppBadge' in navigator — the API is supported in Chromium-based browsers on desktop and Android, but not yet in all browsers.
Updating the badge from the service worker
Section titled “Updating the badge from the service worker”You can also call navigator.setAppBadge from inside the service worker, for example when a push message arrives:
// sw.js — service workerself.addEventListener('push', (event) => { const data = event.data ? event.data.json() : {}; event.waitUntil( Promise.all([ self.registration.showNotification(data.title || 'New message', { body: data.body || '', icon: '/icons/icon-192.png', }), navigator.setAppBadge(data.unreadCount || 1), ]) );});Badging best practices
Section titled “Badging best practices”- Update the badge whenever you show a notification, not only when the app is open.
- Clear the badge in your
notificationclickhandler and when the user views the relevant content. - Do not use the badge to count every background event — only user-visible items (messages, tasks, alerts).
Web Share Target
Section titled “Web Share Target”The Web Share Target API lets your installed PWA appear in the OS share sheet as a destination. When the user shares a photo from their gallery or a link from another browser, your PWA can be listed alongside native apps.
Registering a share target in the manifest
Section titled “Registering a share target in the manifest”Add a share_target entry to your manifest.webmanifest:
{ "name": "My App", "share_target": { "action": "/share", "method": "POST", "enctype": "multipart/form-data", "params": { "title": "title", "text": "text", "url": "url", "files": [{ "name": "media", "accept": ["image/*"] }] } }}When the user shares to your PWA, the browser navigates to /share and POSTs a multipart/form-data body with the fields mapped in params.
Handling the share on the page
Section titled “Handling the share on the page”// /share page scriptconst formData = new FormData(document.forms[0]);const title = formData.get('title');const text = formData.get('text');const url = formData.get('url');const file = formData.get('media');
console.log('Received share:', { title, text, url, file });For a GET-based share (text/URL only), use method: "GET" and the params are appended as query strings.
Web Share API
Section titled “Web Share API”The Web Share API (navigator.share) lets your PWA trigger the OS share sheet to share content from your app to other apps. It is the outgoing counterpart to Share Target.
async function shareContent() { if (!('share' in navigator)) { // Fallback: copy to clipboard await navigator.clipboard.writeText(window.location.href); return; }
try { await navigator.share({ title: 'Check out this recipe', text: 'I found this amazing recipe for sourdough bread.', url: window.location.href, }); console.log('Shared successfully'); } catch (err) { if (err.name !== 'AbortError') { console.error('Share failed:', err); } }}navigator.share must be called from a user gesture (click, tap). Catch AbortError separately — it just means the user dismissed the share sheet.
Sharing files
Section titled “Sharing files”You can also share files (images, PDFs) using the files option. Check support first:
async function shareFile(file) { if (navigator.canShare && navigator.canShare({ files: [file] })) { await navigator.share({ files: [file], title: file.name }); }}Code-only lesson: The Badging API works without a server. Web Share Target requires the PWA to be installed (the manifest change takes effect after installation). Web Share fires the native OS share sheet, which cannot be demoed in an iframe. Run these examples in a real installed PWA.