Client side navigation interceptors #15985
vdjurdjevic
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi, I am working on the PWA application and I would like to discuss a few interesting navigation issues that I encountered so far and propose possible solutions. So, building a PWA, we are trying to make it look and behave like a native mobile application as much as possible for mobile users. And there is one particular problem with web navigation in such a scenario and that is the back button for Android users. Android users use the back button extensively to close modals, popups, sidebars, and stuff like that. The problem is that it just goes back in the browser and change page or close application if on the home page. Apart from closing modals, there is also quite a common pattern with Android (double tap back to close the app) which can't be implemented with web navigation.
So I was thinking about how to implement router interceptors that can execute some logic (for example close modal) and return true or false to indicate if navigation should be blocked. Now, it's not just about closing modals and Android use cases, this can be useful for more scenarios, like preventing navigation if there is unsaved data, etc.
P.S We solve these problems with query parameters, pushing new routes like
?popup=a&popup=b
, but it quickly gets messy. Also, if users share links like that, it's another set of problems. And I am not sure how it can affect SEO. But it's the only way to prevent users from breaking their lovely Android devices every time they try to close hamburger menu, but they leave application instead :)Here are my thoughts on how to solve this in a generic way, to support both the back and forward navigation on any page (home included), and also to support app exit prevention. Since there is no way to stop the browser from popping state from history stack when the user clicks on the back or forward button, the only solution is to add a clone entry for every route and to get the user back to original entry if navigation should be blocked. And to support both directions we should push 2 clones on history stack, one before and one after the original. This way we could prevent navigation with custom interceptor logic, without unmounting the current page. I will try to illustrate this.
This way, whenever pop state lands on entry marked as -1, we execute registered interceptors and if they say that we should block it, we do
history.go(1)
, if not we dohistory.go(-2)
to navigate to middle entry of last page orhistory.go(-1)
to exit if it's a home page. If pop state lands on entry marked as +1, we do the same just in the other direction.This may look hacky, but it's the only way (that I can think of) to enable generic interceptors that work for preventing app exit, navigation in both directions and also keep state without remounting components. What do you think?
Beta Was this translation helpful? Give feedback.
All reactions