-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
onbeforenavigate support for confirming navigation, especially via back arrow #1
Comments
To be more concrete, the pattern that I'm finding tricky/annoying to implement right now looks like:
At this point, what I would like to do is:
The best I can do right now involves immediately reversing the user's navigation action (e.g. by calling |
I think this is needed. The current way of blocking a I am also fine with firing the event only on same-origin navigations (and just using |
Alternatively, something like |
Or similar to the |
I call this feature "resume". How about something like this:
Tricky bits: Last resume token wins. Older tokens do not trigger navigation in history.resume (throw?). Q: what happens if multiple event handlers create resume tokens for same event? |
There are some security concerns with being able to block navigations (especially back navigations), where websites have and continue to abuse the history APIs to prevent users from being able to navigate off their pages. But I think this specific idea has some precedent in beforeunload, which allows you to display a dialog. We could hew to that API, or think about providing something slightly different. |
@tbondwilkinson |
Imagine I'm on a page, and I do a quick history.pushState on page load. Then the user presses back. I catch that back navigation (which is between two states same-origin), and suppress it. The user presses back again, and I suppress it infinitely. The user is now stuck on my page. "security" perhaps isn't the best word to describe this abuse - but you can see how it does clearly lend itself to abuse. But can you use the proposed beforenavigation event to persist the contents of your form? |
I see what you mean. Having some limited ability to show a dialog would probably be good enough for me. All else being the same, I'd prefer to show my current styled dialog, but e.g. if I could throw away the code I have to "rewind" the history state changes, and all it cost me was that the dialog looks like the before unload dialog, then I would make that trade. The "persist form state" option was something we'd considered, but we decided for UX reasons to just require confirmation to exit the form instead – ultimately this is a matter of what my client-side router displays, not directly an issue of the behavior of the history stack – i.e. my router would still have to do some sort of work to stop rendering the form, even after the user has hit "back", as long as he or she is still on my SPA. Blocking the change to the history stack itself is more of a "tidiness" thing. |
First, great project – this set of features looks amazing and would simplify life greatly. This looks like this would let router maintainers move away from figuring out APIs to interface with the browser history API like https://github.com/ReactTraining/history and https://github.com/4Catalyzer/farce and instead focus on just the "routing" bits proper.
To the meat of this – one use case that is particularly annoying to implement in a good way right now is blocking navigation in cases where we have e.g. dirty forms – the SPA equivalent of
beforeunload
event handlers. In general, a modern SPA will often want to show e.g. a custom modal to allow users to confirm whether they actually wish to navigate, which means that we won't know whether the user actually wants to navigate synchronously. Handling this well can require building out some way to "pause" and then "resume" the same navigation action, which potentially involves a lot of finicky state tracking: https://github.com/4Catalyzer/farce/blob/v0.4.1/src/createNavigationListenerMiddleware.js – e.g. what if the user clicks on a link while I'm showing a "are you sure you want to navigate" modal.Note that this issue especially arises in the context of navigation via the back arrow. If I want to "continue" with a navigation that resolves to a
pushState
, it seems like I could just manually callhistory.pushState
, but unless I'm missing something, it could be awkward to "block" a navigation triggered by the back button, becausewindow.history.goBack()
might triggeronbeforenavigate
again.The text was updated successfully, but these errors were encountered: