<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="manifest" href="manifest.json" />
<title>How to create an app badge</title>
<link rel="stylesheet" href="style.css" />
<!-- TODO: Devsite - Removed inline handlers -->
<!-- <script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
const registration = await navigator.serviceWorker.register(
'sw.js',
);
console.log(
'Service worker registered for scope',
registration.scope,
);
});
}
</script>
<script src="script.js" type="module"></script> -->
</head>
<body>
<h1>How to create an app badge</h1>
<ol>
<li>
Watch the favicon. You should see a counter that updates each second
integrated into the favicon.
<img
src="../favicon.png"
style="width: 250px; height: auto"
width="528"
height="74"
alt="Favicon with counter."
/>
</li>
<li>
Install the app by clicking the button below. After the installation,
the button is disabled.
<p>
<button disabled type="button">Install</button>
</p>
</li>
<li>
Watch the app icon in your operating system's task bar. You should see a
counter that updates each second as an app badge.
<img
src="../app-badge.png"
style="width: 80px; height: auto"
width="282"
height="388"
alt="App badge with counter."
/>
</li>
</ol>
<favicon-badge src="../favicon.svg" textColor="#fff" badge="" />
</body>
</html>
html {
box-sizing : border-box ;
font-family : system-ui , sans-serif ;
color-scheme : dark light ;
}
*, * : before , * : after {
box-sizing : inherit ;
}
body {
margin : 1 rem ;
}
img {
height : auto ;
max-width : 100 % ;
display : block ;
}
import 'https://unpkg.com/favicon-badge@2.0.0/dist/FavIconBadge.js' ;
// The `` custom element.
const favicon = document . querySelector ( 'favicon-badge' );
// The install button.
const installButton = document . querySelector ( 'button' );
// Feature detection.
const supportsAppBadge = 'setAppBadge' in navigator ;
// This function will either set the favicon or the native
// app badge. The implementation is dynamically changed at runtime.
let setAppBadge ;
// Variable for the counter.
let i = 0 ;
// Returns a value between 0 and 9.
const getAppBadgeValue = () => {
if ( i > 9 ) {
i = 0 ;
}
return i ++ ;
};
// Function to set a favicon badge.
const setAppBadgeFavicon = ( value ) => {
favicon . badge = value ;
};
// Function to set a native app badge.
const setAppBadgeNative = ( value ) => {
navigator . setAppBadge ( value );
}
// If the app is installed and native app badges are supported,
// use the native app badge.
if (
matchMedia ( '(display-mode: standalone)' ). matches &&
supportsAppBadge
) {
setAppBadge = setAppBadgeNative ;
// In all other cases (i.e., if the app is not installed or native
// app badges are not supported), use the favicon badge.
} else {
setAppBadge = setAppBadgeFavicon ;
}
// Update the badge every second.
setInterval (() => {
setAppBadge ( getAppBadgeValue ());
}, 1000 );
// Only relevant for browsers that support installation.
if ( 'BeforeInstallPromptEvent' in window ) {
// Variable to stash the `BeforeInstallPromptEvent`.
let installEvent = null ;
// Function that will be run when the app is installed.
const onInstall = () => {
// Disable the install button.
installButton . disabled = true ;
// No longer needed.
installEvent = null ;
if ( supportsAppBadge ) {
// Remove the favicon badge.
favicon . badge = false ;
// Switch the implementation so it uses the native
// app badge.
setAppBadge = setAppBadgeNative ;
}
};
window . addEventListener ( 'beforeinstallprompt' , ( event ) => {
// Do not show the install prompt quite yet.
event . preventDefault ();
// Stash the `BeforeInstallPromptEvent` for later.
installEvent = event ;
// Enable the install button.
installButton . disabled = false ;
});
installButton . addEventListener ( 'click' , async () => {
// If there is no stashed `BeforeInstallPromptEvent`, return.
if ( ! installEvent ) {
return ;
}
// Use the stashed `BeforeInstallPromptEvent` to prompt the user.
installEvent . prompt ();
const result = await installEvent . userChoice ;
// If the user installs the app, run `onInstall()`.
if ( result . outcome === 'accepted' ) {
onInstall ();
}
});
// The user can decide to ignore the install button
// and just use the browser prompt directly. In this case
// likewise run `onInstall()`.
window . addEventListener ( 'appinstalled' , ( event ) => {
onInstall ();
});
}
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License , and code samples are licensed under the Apache 2.0 License . For details, see the Google Developers Site Policies . Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2023-07-05 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2023-07-05 UTC."],[],[]]