How to create app shortcuts
App shortcuts help users quickly start common or recommended tasks within your web app. Easy access to those tasks from anywhere the app icon is displayed will enhance users' productivity as well as increase their engagement with the web app.
The modern way #
Define app shortcuts in the web app manifest #
The app shortcuts menu is invoked by right-clicking the app icon in the taskbar (Windows) or dock (macOS) on the user's desktop, or by touch & holding the app's launcher icon on Android.


The app shortcuts menu is shown only for Progressive Web Apps that are installed. Check out Installation in our Learn PWA module to learn about installability requirements.
Each app shortcut expresses a user intent, each of which is associated with a URL within the scope of your web app. The URL is opened when a user activates the app shortcut.
App shortcuts are optionally declared in the shortcuts
array member of the web app manifest. Below is an example of a potential web app manifest.
{
"name": "Player FM",
"start_url": "https://player.fm?utm_source=homescreen",
"shortcuts": [
{
"name": "Open Play Later",
"short_name": "Play Later",
"description": "View the list of podcasts you saved for later",
"url": "/play-later?utm_source=homescreen",
"icons": [{ "src": "/icons/play-later.png", "sizes": "192x192" }]
},
{
"name": "View Subscriptions",
"short_name": "Subscriptions",
"description": "View the list of podcasts you listen to",
"url": "/subscriptions?utm_source=homescreen",
"icons": [{ "src": "/icons/subscriptions.png", "sizes": "192x192" }]
}
]
}
- Chrome 96, Supported 96
- Firefox, Not supported
- Edge 96, Supported 96
- Safari, Not supported
The classic way #
Let user drag links to the bookmark bar #
If the app is not installed yet, you can suggest the user to drag some links from your web page and release them in their browser bookmark bar. That way, they can quickly start common or recommended tasks within your web app.
Further reading #
Demo #
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="dark light" />
<link rel="manifest" href="manifest.json" />
<title>How to create app shortcuts</title>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('sw.js');
});
}
</script>
<script type="module" src="script.js"></script>
</head>
<body>
<h1>How to create app shortcuts</h1>
<ol>
<li>
You can drag these <a href="blue.html">blue page</a> or
<a href="red.html">red page</a> links to the bookmarks bar
and access them later.
</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>
</ol>
</body>
</html>
{
"name": "How to create app shortcuts",
"short_name": "App shortcuts",
"start_url": "../demo.html",
"icons": [
{
"src": "../icons/favicon.png",
"type": "image/png",
"sizes": "512x512"
}
],
"shortcuts": [
{
"name": "Feel blue",
"short_name": "Blue",
"description": "Open a blue webpage",
"url": "../blue.html",
"icons": [{ "src": "../icons/blue.png", "sizes": "192x192" }]
},
{
"name": "Feel red",
"short_name": "Red",
"description": "Open a red webpage",
"url": "../red.html",
"icons": [{ "src": "../icons/red.png", "sizes": "192x192" }]
}
],
"display": "standalone"
}
// The install button.
const installButton = document.querySelector('button');
// 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;
};
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', () => {
onInstall();
});
}