Copyright © 2025 World Wide Web Consortium . W3C ® liability , trademark and permissive document license rules apply.
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 section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C standards and drafts index .
This is a work in progress.
This document was published by the Web Applications Working Group as an Editor's Draft.
Publication as an Editor's Draft does not imply endorsement by W3C and its Members.
This is a draft document and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite this document as other than a work in progress.
This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent that the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .
This document is governed by the 18 August 2025 W3C Process Document .
This section is non-normative.
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 set or 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
setting
a
badge
can
require
permission
from
the
user.
In
this
case,
a
developer
need
to
query
the
"
notifications
"
permissions
status
before
setting
a
badge.
If
the
permission
is
not
granted,
the
developer
will
need
to
prompt
for
permission
via
the
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 :
0
.
An installed web application has an associated badge , which is initialized to "nothing" .
The user agent MAY (re) set an application's badge to "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 set the badge. When a user agent requires such permission , it SHOULD tie the permission grant to the " notifications " permission.
When the badge is set to "flag" , the user agent or operating system SHOULD display an indicator with a non-specific symbol (for example, a colored circle).
When a badge 's value is set to "nothing" , the user agent or operating system SHOULD clear the badge by no longer displaying it.
When the badge is set to a number , the user agent or operating system:
To
set
the
application
badge
of
platform
object
context
to
an
optional
unsigned
long
long
contents
value:
Window
object,
then:
Document
.
InvalidStateError
"
DOMException
.
SecurityError
"
DOMException
.
granted
",
queue
a
global
task
on
the
user
interaction
task
source
given
global
to
reject
promise
with
a
NotAllowedError
and
terminate
this
algorithm.
undefined
.
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 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
Raised
by
@grorg
setting
on
webkit-dev
:
I'd
also
like
to
see
some
specification
text
describing
how
the
browser
should
ignore
multiple
set/clear
operations
executed
in
rapid
succession
(e.g.
to
create
a
blinking
badge)
-
maybe
the
limit
is
one
badge
operation
per
minute
or
something?
We
should
address
this;
it
might
be
a
recommendation
rather
than
a
requirement,
since
it
relates
to
the
UI
of
the
user
agent.
I'd
like
to
see
some
sort
of
"eventual
consistency"
guarantee
which
says
that
the
final
value
you
write
to
clearing
the
application
badge
will
eventually
be
the
one
displayed
to
the
user.
This
prevents
a
situation
where
you
set
"3"
then
10
seconds
later
set
"12",
prevent
distracting
animations
and
due
to
rate
limiting,
the
"12"
never
gets
set,
so
the
reduce
resource
usage.
However,
user
just
sees
"3"
forever.
Instead,
the
rule
should
be
"If
the
UI
hasn't
been
updated
in
>
N
seconds,
update
it
agents
SHOULD
generally
leave
rate
limiting
to
the
new
value.
Otherwise,
set
operating
system,
as
it
is
in
a
timer
to
update
the
UI
better
position
to
the
new
value
in
N
-
(however
long
it
has
been
since
the
last
update)
seconds."
determine
appropriate
throttling
based
on
system
load,
user
preferences,
and
accessibility
considerations.
This section is non-normative.
If the browser is in the control of presenting the badge, it should be possible to define some accessibility guidelines.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY , MUST , SHOULD , and SHOULD NOT in this document are to be interpreted as described in BCP 14 [ RFC2119 ] [ RFC8174 ] when, and only when, they appear in all capitals, as shown here.
Referenced in:
Referenced in: