-
Notifications
You must be signed in to change notification settings - Fork 26
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
First-class "client-side redirect" support #124
Comments
I just realized something that ups the priority here. If you're synchronously trying to do the redirect, as in this example: e.transitionWhile((async () => {
if (shouldRedirect()) {
await navigation.navigate("/redirected"); // (*)
} else {
// ...
}
})()); then you should not use Whereas if you're asynchronously trying to do a redirect, as in this example e.transitionWhile((async () => {
if (await shouldRedirect()) { // Note the await
await navigation.navigate("/redirected"); // (*)
} else {
// ...
}
})()); then you do need to use This seems error-prone and fragile, so adding a first-class helper to smooth this over would be a good idea. |
This example also causes annoying uncaught exceptions, since the first navigation being canceled causes |
A concrete use-case for this might be for SPA app initial navigation. When going directly to a guarded URL, that navigation might be rejected. If the application developer wants to deny the the navigation but doesn't provide a redirect, how should the framework's router handle this? Right now, this can result in "blank" screens on initial page load. Let's say the framework's router allows the application developer to specify a fallback to redirect to if the initial navigation fails, for example the home page. It would also be interested in tracking any redirects associated with that initial navigation so it doesn't eagerly navigate to the home page fallback when it should instead allow any associated redirects to complete. Edit: would the first class redirect support multiple redirects? i.e., navigate to a-> redirects to b -> redirects to c |
I don't quite understand that part; which redirects exist in this setup, besides the one from a guarded URL to the fallback homepage URL?
Yes, I think that's the ideal. To summarize my current thinking of what we could do for redirects:
All of these steps should work if done more than once. |
@domenic The fallback URL would only want to be applied if the initial navigation totally failed. There might be user-defined redirects associated with that navigation and wouldn't want to perform the fallback navigation if a different redirect succeeded. I believe the properties of the navigation you just outlined would make this task easy. |
The scenario shown in #121 uses
navigation.navigate(newURL, { replace: true })
in the middle of anavigate
handler, to perform a "client-side redirect".However, this is not optimal, as doing so makes the original navigation count as interrupted, and thus a "failure", with an
"AbortError"
DOMException
as the failure reason. Notably it firesnavigateerror
onnavigation
, rejectsnavigation.transition.finished
, and rejects the promise returned bynavigation.navigate()
if the navigation started that way.There may be other downsides, e.g. the very-related discussion in #5 talks about the problems with losing same-siteness (for
Sec-Same-Site
) and form data. However, for purely client-side redirects I don't think those particular concerns apply. I guess maybe losing theuserInitiated
bit is in this vein, though.We may want to contemplate a first-class redirect API, perhaps on the
NavigateEvent
object. The semantics would be something like a replace, but with the additional pieces:navigation.transition.finished
delays settling until the new navigation settlesnavigation.navigate()
's return value delays settling until the new navigation settlesnavigation.transition.rollback()
during the new navigation rolls back both navigations.event.signal
for the original event does not fireabort
.event.userInitiated
event.info
andevent.formData
unless told not to?navigation.curentEntry
is the intermediate page (e.g. if you're navigating to/b
and want to redirect to/c
,navigation.currentEntry
will briefly be on/b
before eventually replacing with/c
). There's no way of getting around that.The text was updated successfully, but these errors were encountered: