This specification defines an API that allows [=installed web applications=] to set an application badge, which is usually shown alongside the application's icon on the device's home screen or application dock.
This is a work in progress.
Badges can contribute to notification fatigue for some users. As such, authors need to reserve badges for states that truly merit user attention or action; avoid using them for marketing or engagement gimmicks.
Avoid rapidly changing values that increase distraction or cognitive load.
To support users who do not perceive badges, or have disabled them at the system level, authors are encouraged to present the same state within application UI using accessible patterns (e.g., clearly labeled in-app status indicators).
async function updateMailBadge() { // Check if the API is supported. if (!navigator.setAppBadge) return; const unreadCount = await getUnreadMailCount(); // Try to set the app badge. try { await navigator.setAppBadge(unreadCount); } catch (e) { // The badge is not supported, or the user has prevented the app // from setting a badge. } }
The badge might show up on the application's icon in the operating system. If multiple API calls within the same application [=badge/set=] or [=badge/clear=] a badge, the most recent one takes effect, and may continue being seen even after an application is closed.
async function showPlayerTurn(playerTurnId) { if (playerTurnId === localPlayerId) await navigator.setAppBadge(); else await navigator.clearAppBadge(); }
On some operating systems [=badge/setting=] a badge can require permission from the user. In this case, a developer need to query the "[=notifications=]" permissions status before [=badge/setting=] a badge. If the permission is not granted, the developer will need to prompt for permission via the {{Notification}}.{{Notification/requestPermission()}}.
async function checkPermission() { permission = await navigator.permissions.query({ name: "notifications", }); const button = document.getElementById("permission-button"); if (permission.state === "prompt") { // Prompt the user to grant permission. button.hidden = false; button.addEventListener("click", async () => { await Notification.requestPermission(); checkPermission(); }, { once: true }); return; } button.hidden = true; }
A badge is intended as a mechanism for [=installed web applications=] to notify the user that there is some new activity that might require their attention, or as a way of indicating a small amount of information, such as an unread count.
A [=badge=] can have one of the following values:
An [=installed web application=] has an associated [=badge=], which is initialized to [=badge/"nothing"=]. The operating system stores and manages the badge value, with the [=user agent=] acting as an intermediary to communicate badge changes to the OS.
The user agent MAY (re)[=set=] an application's badge to [=badge/"nothing"=] at its discretion (for example, following system conventions).
When the application's badge is set, the [=user agent=] or operating system SHOULD display the application's [=badge=] alongside the primary iconic representation of the application in the user's operating system (for example, as a small overlay on top of the application's icon on the home screen on a device).
A user agent MAY require [=express permission=] from the user to [=badge/set=] the badge. When a user agent requires such [=permission=], it SHOULD tie the permission grant to the "[=notifications=]" permission.
When the [=badge=] is [=badge/set=] to [=badge/"flag"=], the [=user agent=] or operating system SHOULD display an indicator with a non-specific symbol (for example, a colored circle). If the platform does not support displaying a [=badge/"flag"=] badge, the [=user agent=] SHOULD display the badge using the closest available representation that indicates the presence of a badge (e.g., the value "1"), rather than [=badge/clearing=] the badge entirely.
When a [=badge=]'s value is [=badge/set=] to [=badge/"nothing"=], the [=user agent=] or operating system SHOULD clear the [=badge=] by no longer displaying it.
When the [=badge=] is [=badge/set=] to a [=badge/number=], the [=user agent=] or operating system:
Different operating systems have varying capabilities for displaying badges. The ultimate display behavior is controlled by the operating system and might be further modified by user settings or system conventions. When communicating badge information to the operating system, [=user agents=] SHOULD preserve the semantic intent of the badge request:
[SecureContext] interface mixin NavigatorBadge { Promise<undefined> setAppBadge( optional [EnforceRange] unsigned long long contents ); Promise<undefined> clearAppBadge(); }; Navigator includes NavigatorBadge; WorkerNavigator includes NavigatorBadge;
User agents that never display application badges SHOULD NOT [=interface/include=] {{NavigatorBadge}}.
When the {{NavigatorBadge/setAppBadge()}} method is called, the user agent MUST [=set the application badge=] of [=this=] to value of the |contents:unsigned long long| argument.
When the {{NavigatorBadge/clearAppBadge()}} method is called, the user agent MUST [=set the application badge=] of [=this=] to 0.
To set the application badge of platform object |context:platform object| to an optional {{unsigned long long}} |contents:unsigned long long| value:
The API is write-only by design. There is no way for a site to read back the value of a badge that was previously set, to ensure that the application badge cannot be used as a storage or fingerprinting mechanism.
The [=user agent=] or operating system MAY [=badge/clear=] a [=badge=] at its discretion, and to follow any system conventions (for example, when the system is reset).
User agents MAY rate-limit badge [=set the application badge|setting=] or [=badge/clear|clearing=] the application badge to prevent distracting animations and reduce resource usage. However, user agents SHOULD generally leave rate limiting to the operating system, as it is in a better position to determine appropriate throttling based on system load, user preferences, and accessibility considerations.
Application badges convey status that can require the user's attention. Because badges are often presented outside the web content area (for example, on an app icon in the dock), user agents need to ensure that the information remains accessible and controllable through platform accessibility features and user preferences.
User agents SHOULD expose the current [=badge/value=] (including [=badge/"flag"=] vs. [=badge/number=]) through platform accessibility APIs so that assistive technologies can present it on demand (for example, when the user focuses the application icon).
User agents SHOULD NOT automatically announce badge changes; instead, they SHOULD follow platform conventions that avoid unsolicited interruptions.
As badges are typically drawn by the underlying platform, visual affordances are typically handled there. Nevertheless, user agents and platforms need to consider:
User agents SHOULD integrate with platform accessibility settings and themes.
User agents SHOULD reflect OS-level per-application badge preferences (for example, when the operating system disables badges for an app).