Save Bar not blocking navigation - `A router only supports one blocker at a time`
nick-potts opened this issue · 5 comments
Describe the bug
The SaveBar isn't stopping navigation in my remix template. It shakes but the navigation still occurs.
In the console, I have the message A router only supports one blocker at a time
. I'm not using useBlocker anywhere else in my app. I've tried both programmatically and data-save-bar, but both have the same issue. My app has been getting rejected from built-for-shopify because of this, but I can't find any acceptable solution.
To Reproduce
I've made a minimal reproduction using the stock remix template:
https://github.com/nick-potts/app-bridge-save-bar
Both the useNavigate and tabs don't block navigation.
You have to use the leaveConfirmation method before initiating your navigation. This is documented here: https://shopify.dev/docs/api/app-bridge-library/apis/save-bar#savebar-propertydetail-leaveconfirmation
Example in Remix:
await shopify.saveBar.leaveConfirmation();
navigate("route-name");
The leaveConfirmation promise will resolve only if the save bar is not dirty, hence blocking the navigation.
How would I achieve that with the tabs component?
https://github.com/nick-potts/app-bridge-save-bar/blob/09d4aa9c10a728907eb06cae55db6c190f498de2/app/routes/app._index.tsx#L57
You can’t. You will need to use an onClick and manually perform the validation using the remix use navigate hook
Hi @bakura10 I have a question about your comment.
The leaveConfirmation promise will resolve only if the save bar is not dirty, hence blocking the navigation.
Does that mean that it rejects if the save bar is dirty, or does that mean it has an unresolved promise just sitting around? Would that cause a memory leak? It seems like it could lead to a bunch of unresolved promises in memory if it doesn't resolve or reject when called. Is there a mechanism to clean those up after page navigation or something?
I can't answer about that, I'm not a Shopify developer and the app bridge source is not open sourced. But I suppose the promise reject ?