Summary
Please enhance the Shopify POS UI Extensions Navigation API so extensions can determine when a native Back transition has visually completed.
Ideally, navigation.back() would return a promise, or the Navigation API would expose native transition lifecycle events.
This is needed because Shopify POS can replay a cached version of the departing extension screen during its native Back animation, even after the extension has rendered and displayed a newer loading state.
Environment
- Extension surface: Shopify POS UI Extension
- Target:
pos.home.modal.render - API version:
2026-07 - UI framework: Preact with Shopify POS web components
- Navigation method:
navigation.back() - Shopify POS version:
11.11.1
Current behaviour
Our extension has a multi-screen ordering workflow:
- The merchant opens a collection.
- They select a product.
- The extension navigates to a Customise screen.
- They tap Add & Order More.
- The extension adds the product and calls
navigation.back()to return to the collection.
Before requesting Back navigation, the extension:
- Replaces the Customise screen with a full-screen Shopify
s-spinner. - Waits for the new state to render.
- Waits through two
requestAnimationFramecallbacks. - Keeps the spinner visible for at least 500 milliseconds.
- Calls
navigation.back().
The spinner renders successfully and is visibly displayed. However, after navigation.back() is called, the native Shopify POS transition briefly displays a cached version of the original Customise screen before showing the collection.
The visible sequence is:
Loading spinner
→ cached Customise screen briefly reappears
→ collection screen
This is not caused by the extension clearing its loading state. Our successful-navigation path deliberately keeps the loading state mounted, and our automated tests confirm it remains active after the Back request.
The behaviour also persists after waiting 500 milliseconds before calling navigation.back().
Expected behaviour
When the extension calls navigation.back(), Shopify POS should either:
- Use the extension’s most recently committed visual frame during the native transition; or
- Allow the extension to determine when the native transition has finished.
The expected visual sequence is:
Loading spinner
→ collection screen
The original Customise screen should not reappear after the spinner has been rendered.
Requested API improvements
Any of the following would help resolve this problem:
Preferred: Awaitable Back navigation
Allow navigation.back() to return a promise that resolves after the native visual transition has completed:
await navigation.back();
This would allow the extension to retain its loading state until Shopify POS has finished the transition.
Alternative: Native transition lifecycle events
Expose events such as:
navigation.addEventListener("transitionstart", handler);
navigation.addEventListener("transitionend", handler);
The existing currententrychange event identifies a history-entry change, but it does not indicate that the native animation has visually completed.
Alternative: Latest-frame guarantee
Guarantee that the native transition uses the extension’s latest committed render rather than an older cached frame.
Additional useful options
The following Navigation API capabilities could also provide safe alternatives:
- An option to disable the native transition animation.
- A
replacenavigation mode that does not add another history entry. - A method to explicitly prepare or commit the departure frame before Back navigation.
Merchant and user impact
This issue affects high-frequency POS workflows. Staff may use Add & Order More repeatedly while serving customers.
The cached-screen flash:
- Makes the extension appear to reload or navigate incorrectly.
- Can make staff believe the add action failed.
- Creates a visually unstable experience during rapid ordering.
- Encourages developers to add artificial delays that do not reliably solve the underlying native transition behaviour.
Current workaround and its limitation
In POS Cafe 3.58.19, we stopped replacing the entire Customise page with a spinner.
Instead, we:
- Keep the Customise page structurally unchanged.
- Show Shopify’s native loading state on the Add & Order More button.
- Disable the remaining controls.
- Wait for at least 500 milliseconds.
- Request Back navigation.
This makes the cached frame less noticeable because it resembles the page already being displayed.
Although the workaround improves the experience, it prevents us from using the clearer full-screen loading treatment that we would prefer for this workflow.
Evidence available
We can provide:
- A real-device recording of the issue.
- A slow-motion copy of the transition.
- The extension API version and relevant navigation code.
- A comparison recording showing our button-loading workaround.
Thank you so much,
Adam