LEARNING OBJECTIVES ⌵
- Configure the
shortcutsarray inmanifest.webmanifestto expose OS right-click / long-press Quick Action context menus. - Implement the Badging API using
navigator.setAppBadge()andnavigator.clearAppBadge()to indicate unread notifications. - Update app icon badges directly from the Service Worker background thread in response to incoming Web Push notifications.
- Design seamless deep-linking navigation flows for app shortcut targets with specialized launch query parameters.
📖 The Mental Model & Story (Intuitive Foundation)
Think about how you interact with native messaging and email apps on your smartphone or desktop:
- When you glance at your phone's home screen or your computer's dock/taskbar, you don't have to open the email app to see if you have unread messages. A little red badge with the number "5" sits directly on the app icon (The Badging API).
- When you want to immediately compose a message or scan a QR code, you don't launch the app, wait for the home screen to load, and navigate through three nested menus. Instead, you long-press the app icon on Android/iOS or right-click the taskbar icon on Windows/macOS, and a popup menu appears with direct shortcuts: "New Chat", "Scan Code", or "My Orders" (App Shortcuts).
Historically, web applications had no way to display numeric indicators on the operating system taskbar or provide contextual OS jump lists. The Badging API and App Shortcuts API bridge this gap, giving PWAs identical desktop and mobile launcher capabilities to native Swift, Kotlin, and C# apps.
Technical Deep Dive & Specifications
App Shortcuts in the Web App Manifest
The shortcuts member is an array of objects defined within manifest.webmanifest. Operating systems render these shortcuts when the user long-presses the home screen icon on mobile or right-clicks the pinned taskbar icon on desktop:
+----------------------------------------------+
| OS APP ICON CONTEXT MENU |
+----------------------------------------------+
| [🚀 Orbit Task Manager] |
+----------------------------------------------+
| 📝 New Task (/tasks/new?src=quick) |
| 🔍 Search Inbox (/search?src=quick) |
| 📊 View Analytics (/stats?src=quick) |
+----------------------------------------------+
| App Info / Uninstall |
+----------------------------------------------+
{
"name": "Orbit Task Manager",
"short_name": "Orbit",
"start_url": "/dashboard.html",
"display": "standalone",
"shortcuts": [
{
"name": "Create New Task",
"short_name": "New Task",
"description": "Directly open the new task composer",
"url": "/tasks/new.html?shortcut=create",
"icons": [{ "src": "/icons/shortcut-new.png", "sizes": "96x96" }]
},
{
"name": "Search Records",
"short_name": "Search",
"description": "Instant search across all project items",
"url": "/search.html?shortcut=search",
"icons": [{ "src": "/icons/shortcut-search.png", "sizes": "96x96" }]
}
]
}
The Badging API Specification
The Badging API operates on the navigator object in window contexts and on the self.navigator object inside Service Worker global scopes.
+-----------------------------------------------------------------------------------+
| THE BADGING API |
+-----------------------------------------------------------------------------------+
| 1. Numeric Badge: navigator.setAppBadge(42) |
| --> Displays "[ 42 ]" badge on dock/taskbar icon |
| |
| 2. Unflagged / Generic Dot: navigator.setAppBadge() |
| --> Displays a solid notification dot on platforms that don't support numbers|
| |
| 3. Clear Badge: navigator.clearAppBadge() or navigator.setAppBadge(0) |
| --> Completely removes the badge from the application icon |
+-----------------------------------------------------------------------------------+
| Method | Context | Parameters | Return Type | Description |
|---|---|---|---|---|
navigator.setAppBadge(count?) |
Window & Service Worker | count (Optional integer >= 1) |
Promise<void> |
Sets a numeric badge or generic flag on the app icon. |
navigator.clearAppBadge() |
Window & Service Worker | None | Promise<void> |
Removes the current badge from the app icon. |
💻 Interactive Code Playground
Starter Code: Dynamic Badging & Shortcut Handler
Below is a complete application demonstrating interactive badging controls, task counts, and shortcut URL parameter detection.
Line-by-Line Code Breakdown
- Line 72–77 (
new URLSearchParams(window.location.search)): Parses query strings (e.g.?shortcut=create) passed when the user taps an OS shortcut context menu item, routing the user to the designated sub-view. - Line 81 (
'setAppBadge' in navigator): Feature-detects Badging API support before making method calls. - Line 84 (
await navigator.setAppBadge(count)): Asynchronously instructs the OS desktop shell (Windows Explorer, macOS Dock, Android Launcher) to draw the numeric overlay on the installed icon. - Line 87 (
await navigator.clearAppBadge()): Removes any existing badge or indicator from the icon. - Line 101 (
await navigator.setAppBadge()): Calling without arguments renders an uncounted notification flag/dot on platforms that support dot indicators.
Expected Browser Render Output
App Badging & Shortcuts
Managing OS-level taskbar indicators and deep-link launcher shortcuts.
[ ⚡ Launched via OS Quick Action: CREATE ]
Unread Notification Counter
Current Unread Count: [ 3 ]
[ Add Notification (+1) ] [ Set Dot Flag ] [ Clear Badge ]
(On Windows Taskbar / macOS Dock):
App Icon displays small red circle with "3" superimposed over the logo.🏋️ Hands-On Exercise
🎯 The Challenge: Build a Background Push Notification Badge Handler
Instructions:
- In
sw.js, listen for thepushevent triggered by a server push payload. - Read the unread count from the push JSON payload (
const data = event.data.json()). - Call
self.navigator.setAppBadge(data.unreadCount)insideevent.waitUntil(). - Listen for
notificationclickinsw.jsand clear the badge usingself.navigator.clearAppBadge()when the user opens the notification.
🏁 Starter Code Sandbox
⚠️ Common Pitfalls
- Passing Negative or Non-Integer Numbers to
setAppBadge(): Callingnavigator.setAppBadge(-5)ornavigator.setAppBadge(3.14)will throw aTypeError. The parameter must be a positive integer >= 1 (or 0 to clear). - Assuming Badges Work on Uninstalled Websites: On desktop Chrome/Edge, badges only render when the website is installed as a PWA or pinned to the taskbar/dock. Calling the API on an ordinary tab has no visible OS effect (though it won't throw an error).
- Using Massive Multi-Megabyte Icons for Manifest Shortcuts: Shortcut icons should be small PNGs (
96x96or192x192). Oversized icons slow down manifest parsing during OS registration.
💡 Pro Tips
- Limit Manifest Shortcuts to 4 Items: While the W3C spec allows many shortcut entries, mobile operating systems (Android, iOS) typically display only the first 3 to 4 items in the quick actions menu. Place your highest-value actions first.
- Add Tracking Parameters to Shortcut URLs: Always append distinct query parameters like
?source=manifest_shortcut_newto each shortcut'surl. This gives your analytics pipeline exact visibility into how frequently power users leverage OS launcher menus.
📌 Key Takeaways
- The
shortcutsarray inmanifest.webmanifestcreates native OS right-click and long-press launcher menus. - The Badging API (
navigator.setAppBadge(),navigator.clearAppBadge()) sets numeric or dot indicators on the installed app icon. - Calling
setAppBadge()without arguments displays an unnumbered notification dot. - Badges can be updated from background Service Workers during
pushevents usingself.navigator.setAppBadge(). - Always detect support via
'setAppBadge' in navigatorto ensure graceful degradation. - --