Hello, @Paige-Shopify.
I’m sorry to bother, but what’s the current status of this ticket? I’m experiencing another symptom of (what I think is) the same root cause - when navigating, a new runtime appears to be created, causing all sorts of weirdness.
Example snippet below:
function ExampleThree() {
const lines = shopify.cart.current.value.lineItems;
console.log(
`\n ${new Date().toISOString()} ExampleThree, navigation.currentEntry.url -`,
navigation.currentEntry.url
);
if (navigation.currentEntry.url === "/test") {
return (
<s-page heading="Test page">
<s-button
onClick={async () => {
// NOTE: Ensure at least one line item is in the cart
await shopify.cart.bulkAddLineItemProperties([
{
lineItemUuid: lines[0].uuid,
properties: {
test: "1",
},
},
]);
navigation.back();
}}
>
Bulk add line item properties & go back
</s-button>
</s-page>
);
}
return (
<s-page heading="Initial page">
<s-button onClick={() => navigation.navigate("/test")}>
Go to test page
</s-button>
</s-page>
);
}
To reproduce:
- Ensure there’s at least one line item in the cart
- Open the POS action extension
- Tap Go to test page
- Tap Bulk add line item properties & go back
Note that navigation.back was initiated (noticeable navigation animation), but the same page remains active. After that pressing the chevron button closes the extension instead of going back.
Beyond very basic use cases, the new POS navigation API is unusable. My understanding is that the React UI extensions will no longer be supported as of July 2026, which leaves us with slightly more than two months to migrate. This is very concerning.
Currently, the only alternative I can think of is to dynamically update the singleton page component and not use the new navigation API. POC below:
function ExampleFour() {
const [screens, setScreens] = useState<ScreenName[]>([ScreenName.Cart]);
console.log(
`\n ${new Date().toISOString()} Example, screens -`,
screens.join()
);
return (
<s-page heading={screens[screens.length - 1]}>
<s-stack rowGap="base">
<s-button
onClick={() => {
setScreens((screens) => screens.slice(0, -1));
// navigation.back();
}}
>
Back
</s-button>
<s-button
onClick={async () => {
setScreens((screens) => [...screens, ScreenName.Line]);
// await navigation.navigate("/");
}}
>
Line
</s-button>
<s-button
onClick={async () => {
setScreens((screens) => [...screens, ScreenName.Cart]);
// await navigation.navigate("/");
}}
>
Cart
</s-button>
<s-button
onClick={async () => {
try {
await shopify.cart.setCustomer({
id: 1,
});
} catch (e) {
console.error("set customer error -", e);
}
}}
>
Set customer
</s-button>
</s-stack>
</s-page>
);
}
All of the earlier mentioned issues go away and I’d be happy to rely on the custom navigation solution if it was possible to override the top left (Back/Close) button.