Quick actions
Home-screen shortcuts on the app icon, configured per brand.
Long-press the app icon and up to four shortcuts appear — Wishlist, Cart, Account, or anything else you point at a screen. They are config-driven, so a brand changes them in Studio without an app release.
Arrived in 0.28.0. It ships a native module, so picking it up needs a store release, not a config publish.
What you have to build
Nothing. useQuickActions runs inside brewery's shell, so any app on the shell already registers the shortcuts and routes taps. There is no block to place and no hook to call.
The one requirement is the dependency:
// package.json
"@app-brew/quick-actions": "0.28.0" // workspace:* inside the monorepoIt autolinks — pod install for iOS, a Gradle sync for Android. Both app templates already include it, and so does anything ejected from 0.28.0 onward. Apps ejected before September 2026 need it added by hand.
Configuring the actions
Actions live at store.quickActions in app config. Leave it unset and the app falls back to Wishlist, Cart and Account — each dropped if the app has no such screen, so a default never points somewhere that does not exist.
{
"store": {
"quickActions": [
{
"id": "track-order",
"title": "Track order",
"subtitle": "See where it is",
"icon": "https://cdn.example.com/icons/truck.png",
"iosSymbol": "shippingbox",
"link": { "kind": "screen", "value": "orders" },
"active": true
}
]
}
}| Field | Purpose |
|---|---|
id | Stable identity, and what a tap reports back |
title | Label on the shortcut |
subtitle | Second line. iOS renders it; the Android module ignores it |
icon | Android — an image URL, downloaded to a bitmap on device, or a bundled drawable name |
iosSymbol | iOS — an SF Symbol name |
link | Where a tap goes. Same Link shape as everywhere else |
active | false hides it without deleting it. Absent means shown |
The schema and defaults live in @gauntlet/types, shared by Studio validation and device registration so the two cannot drift.
Four things that will bite you
Four actions, maximum
MAX_QUICK_ACTIONS is 4 — an iOS limit, applied on both platforms. Studio stops you adding a fifth; the app silently drops extras beyond the fourth.
Icons are per-platform and not interchangeable. iOS cannot render a runtime image on a home-screen action, so it draws iosSymbol and ignores icon. Android does the opposite. Give an action only one of the two and it renders on only one platform.
mailto: links do not open the mail client. They route to the in-app compose screen with the recipient parsed out. If the shopper is not signed in they go through sign-in first and land on compose afterwards.
Order is already handled. Android stacks dynamic shortcuts in reverse of add order, so the hook registers them reversed. Configured order is what shoppers see on both platforms — do not compensate for it yourself.
When shortcuts register
The hook waits for config to load, then re-registers whenever the resolved list changes. The comparison is by value, so an equal-but-new array from a re-render does not churn the OS.
A tap that arrives before navigation is ready is held until it is, which is what makes cold-start taps land on the right screen instead of the home tab.
Debugging
| Symptom | Usual cause |
|---|---|
| No shortcuts at all | Config has not loaded, or isShortcutSupported() is false — older OS, or a launcher that does not support them |
| Android has them, iOS does not | The pod was never installed after adding the dep, or the actions have no iosSymbol |
| Tap opens the app but does not navigate | The link target does not resolve — check the screen id exists in config |
| A stale shortcut lingers | The hook clears all shortcuts before re-adding, so registration threw partway. Check the native log |
Where the code lives
Native module: native-libs/native-quick-actions — a vendored fork of @rn-org/react-native-shortcuts carrying two Appbrew deltas, Android remote-URL icon loading and an iOS self-installing delegate swizzle that means apps need no AppDelegate changes. JS wiring: useQuickActions in @gauntlet/brewery. Schema and defaults: @gauntlet/types.

