Manifest · Manifest member
shortcuts manifest member
Published
shortcuts is an array of quick-action links that the operating system lists when the user
long-presses (Android) or right-clicks (Windows taskbar, macOS Dock) the installed app’s
icon. Each entry opens one in-scope URL directly, bypassing start_url, which makes the
member the manifest-level equivalent of a native app’s jump list: “New message”, “Inbox”,
“Today” and similar high-frequency destinations.
Chrome 85 on Android, Chrome 96 and Edge 96 on desktop, and Samsung Internet 14.0 read the
member; Safari 17.4 on macOS adds it for Dock apps (BCD html.manifest.shortcuts). Safari on
iOS and Firefox 157 do not, so on those platforms the entries are parsed and discarded.
Member
Section titled “Member”- Type: array of shortcut objects. Each object has
name(required, the menu label),url(required, resolved against the manifest URL and required to be withinscope), and the optionalshort_name,description, andicons(same image-object shape as the top-levelicons). - Default: an empty array. A non-array value is dropped with the parser message
property 'shortcuts' ignored, type array expected. - Example value:
[{ "name": "New invoice", "url": "/app/invoice/new", "icons": [{ "src": "/icons/new-96.png", "sizes": "96x96" }] }].
Chromium validates each entry on its own. An entry without name or url is skipped with
property 'name' of 'shortcut' not present. or property 'url' of 'shortcut' not present.,
and an out-of-scope url is skipped with property 'url' of 'shortcut' ignored. url should be within scope of the manifest. (manifest_parser.cc). The rest of the array survives, so a
single bad entry removes one menu item, not the whole menu.
How many entries the OS shows is a platform limit, not a manifest one: the Android launcher menu shows 4, the Windows jump list 10, and the macOS Dock menu 10 (web.dev, “Get things done quickly with app shortcuts”). Chromium truncates the array in order, so the first entries are the ones that survive on the tightest platform.
Examples
Section titled “Examples”The three examples build on one invoicing app whose scope is /app/.
Three actions with icons and a space-saving short_name
Section titled “Three actions with icons and a space-saving short_name”The first entry carries every optional field; the second shows the minimum the parser
accepts. short_name replaces name on Android when the launcher runs out of room, so keep
it to one or two words.
{ "scope": "/app/", "start_url": "/app/", "shortcuts": [ { "name": "New invoice", "short_name": "New", "description": "Start a blank invoice", "url": "/app/invoice/new?source=shortcut", "icons": [{ "src": "/icons/shortcut-new-96.png", "sizes": "96x96", "type": "image/png" }] }, { "name": "Unpaid invoices", "url": "/app/invoices?filter=unpaid&source=shortcut", "icons": [{ "src": "/icons/shortcut-unpaid-96.png", "sizes": "96x96", "type": "image/png" }] }, { "name": "Dashboard", "url": "/app/dashboard?source=shortcut" } ]}A url of /billing/ would be dropped here because it falls outside /app/, and a
description is read by assistive technology rather than drawn in the menu.
Counting shortcut launches without a dedicated API
Section titled “Counting shortcut launches without a dedicated API”No event tells the page that it was opened from a shortcut. The query string on each url is
the only signal, so read it once at startup and strip it so that in-app navigation does not
carry it along. When the parameter is absent the launch came from the icon, a link, or a
notification, and the code records nothing.
const params = new URLSearchParams(location.search);if (params.get('source') === 'shortcut') { navigator.sendBeacon('/analytics', JSON.stringify({ launch: 'shortcut', path: location.pathname })); params.delete('source'); const clean = `${location.pathname}${params.size ? `?${params}` : ''}${location.hash}`; history.replaceState(history.state, '', clean);}history.replaceState() keeps the back button sane; without it the first in-app navigation
would record the tagged URL as a history entry.
Monochrome 96 px icons that survive the menu’s size
Section titled “Monochrome 96 px icons that survive the menu’s size”Desktop menus draw shortcut icons at 16 to 32 CSS pixels and tint nothing, so a detailed, multi-colour glyph turns to mud. A single-colour PNG with generous padding reads at every size the menu uses, and one 96 px asset per entry satisfies the DevTools check.
{ "icons": [ { "src": "/icons/shortcut-new-96.png", "sizes": "96x96", "type": "image/png" }, { "src": "/icons/shortcut-new.svg", "sizes": "any", "type": "image/svg+xml" } ]}The SVG entry is optional: Chromium rasterises it when present, and the PNG remains the fallback for the Windows jump list, which does not accept SVG.
See also
Section titled “See also”- App shortcuts after install
- Add app shortcuts
- scope manifest member
- icons manifest member
- Web Application Manifest: shortcuts member (w3.org)
- Get things done quickly with app shortcuts (web.dev)
Specifications
| Specification | Status |
|---|---|
| manifest: shortcuts | W3C |
- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Android) | Yes | 85 | low | source | — |
| Chrome (Desktop) | Yes | 96 | low | source | — |
| Edge (Desktop) | Yes | 96 | low | source | — |
| Samsung Internet | Yes | 14.0 | low | source | — |
| Firefox (Desktop) | No | — | low | source | 1 |
| Safari (iOS) | No | — | low | source | 2 |
| Safari (macOS) | Yes | 17.4 | low | source | — |
- No desktop install path consuming shortcuts.
- Not supported on iOS.