Skip to content
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

feat(router): Set a different browser URL from the one for route matching #53318

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

atscott
Copy link
Contributor

@atscott atscott commented Dec 2, 2023

This feature adds a property to the NavigationBehaviorOptions that allows developers to define a different path for the browser's address bar than the one used to match routes. This is useful for redirects where you want to keep the browser bar the same as the original attempted navigation but redirect to a different page, such as a 404 or error page.

fixes #17004

@atscott atscott added feature Issue that requests a new feature area: router target: minor This PR is targeted for the next minor release labels Dec 2, 2023
@ngbot ngbot bot modified the milestone: Backlog Dec 2, 2023
@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label Dec 2, 2023
@jnizet
Copy link
Contributor

jnizet commented Dec 2, 2023

I had the feeling that the preferred way of redirecting was to return a UrlTree from the guard rather than imperatively navigating from the guard.
How would we get this behavior when returning a UrlTree?

Also, I must say that using UrlTrees is quite confusing, especially for beginners. Common navigations (using routerLink or router.navigate) use strings or arrays of segments to navigate, but in order to redirect, we have to transform the string/array into a UrlTree, which is not intuitive.
Even with the current state of this PR, if the goal is to keep the currently requested URL, couldn't we simply pass a boolean option rather than an UrlTree option?

@atscott
Copy link
Contributor Author

atscott commented Dec 4, 2023

I had the feeling that the preferred way of redirecting was to return a UrlTree from the guard rather than imperatively navigating from the guard.

Yes, redirects should generally go through that mechanism. router.navigate...; return false isn't a true redirect as far as the Router's concerned. It's a new navigation that cancels and supersedes the current one. Redirects with the UrlTree return allow you to keep the original Promise from navigate and not resolving it until the redirect navigation completes. We can track it more directly as an actual redirect and treat it as a direct continuation of the initial navigation.

How would we get this behavior when returning a UrlTree?

It should and will be available, but I didn't feel that this feature needed to be blocked on having that available.

Unfortunately the UrlTree redirects don't provide a way to defined extras and was a design decision at the time (#27148 (comment)). I think it's clear now that this wasn't right and it'll be available in v18 with #45023 (expanding the type is a breaking change).

Also, I must say that using UrlTrees is quite confusing, especially for beginners. Common navigations (using routerLink or router.navigate) use strings or arrays of segments to navigate, but in order to redirect, we have to transform the string/array into a UrlTree, which is not intuitive.

Agreed. There are at least two reasons this PR is still in draft mode and one of them is that I'm not yet decided on the behavior here with urlHandlingStrategy and urlSerializer (that includes string as an option). At the moment, I'm leaning towards not serializing a string and not using UrlHandlingStrategy.merge with the property value. In this way, the browserUrl property can also be used as a way to manually avoid UrlHandlingStrategy behavior.

Even with the current state of this PR, if the goal is to keep the currently requested URL, couldn't we simply pass a boolean option rather than an UrlTree option?

Two things here: It is a goal but I wouldn't say it's necessarily the only goal. The feature as proposed here is a lot more flexible than a boolean and could be used for other use-cases. Additionally, as described above, the router.navigate...; return false; pattern isn't really a redirect. I don't think a boolean directly in the navigation extras that depends on the current router/navigation state (if there is one) is a great API. That said, I do think we could consider a shortcut to getting this behavior with a boolean when RedirectCommand is available since that, by definition, is only working in the context of an actual redirect.

@jnizet
Copy link
Contributor

jnizet commented Dec 4, 2023

Thanks for the detailed explanations @atscott

@atscott atscott force-pushed the differentBrowserUrl branch 5 times, most recently from f953fd6 to f12c0fc Compare December 4, 2023 20:06
@atscott atscott marked this pull request as ready for review March 7, 2024 00:51
@ChristofFritz
Copy link

Thank you so much for building this @atscott ! We'll be using this the second it get's released.

@pullapprove pullapprove bot requested a review from AndrewKushnir May 3, 2024 23:21
Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: public-api

…hing

This feature adds a property to the `NavigationBehaviorOptions` that
allows developers to define a different path for the browser's address
bar than the one used to match routes. This is useful for redirects
where you want to keep the browser bar the same as the original
attempted navigation but redirect to a different page, such as a 404 or
error page.

fixes angular#17004
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: router detected: feature PR contains a feature commit feature Issue that requests a new feature target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Render 404 page with CanActivate guard without aborting navigation
4 participants