# shortcuts manifest member

> The shortcuts array adds quick-action entries to the long-press or right-click menu of an installed PWA icon, each opening an in-scope URL instead of start_url.

`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

- **Type**: array of shortcut objects. Each object has `name` (required, the menu label),
  `url` (required, resolved against the manifest URL and required to be within `scope`),
  and the optional `short_name`, `description`, and `icons` (same image-object shape as the
  top-level `icons`).
- **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.

:::observed
Chrome 155 on macOS 26 (English UI), DevTools > Application > Manifest, section
**Shortcuts**: an entry whose `icons` array lacks a 96 px image is flagged with
`Shortcut #1 should include a 96×96 pixel icon`, and the section always carries the line
`The maximum number of shortcuts is platform dependent. Some shortcuts may be not available.`
Right-clicking the app's Dock icon lists each surviving `name` above the standard **Options**
and **Quit** items.
:::

## Examples

The three examples build on one invoicing app whose `scope` is `/app/`.

### 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.

```json
{
  "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

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.

```js
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

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.

```json
{
  "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

- [App shortcuts after install](/reference/installation/install-shortcuts/)
- [Add app shortcuts](/guides/shortcuts/)
- [scope manifest member](/reference/manifest/scope/)
- [icons manifest member](/reference/manifest/icons/)
- [Web Application Manifest: shortcuts member](https://www.w3.org/TR/appmanifest/#shortcuts-member) (w3.org)
- [Get things done quickly with app shortcuts](https://web.dev/articles/app-shortcuts) (web.dev)