Search code examples
angularangular-routingangular-router

Angular - how to land always on the start page when refreshing the browser from a secondary route


I have a simple scenario. My app starts with a default component, let's say StartComponent, which is reached via Angular router using a route named start. So in the browser bar I see something like myhost/start.

The logic of the app then brings me to a second component, SecondComponent, when I navigate to the route named second, so in the browser bar I see myhost/second.

If now I do a refresh of the browser, e.g. via Command-R or Ctrl-F5, I land again on SecondComponent.

What I would like to see happen though is that the refresh of the browser brings me again to StartComponent regardless of where I do the refresh from.

Which is the cleanest way to reach this behavior?


Solution

  • It's basically the same strategy as redirecting to a login if the user isn't logged in. You can use a CanActivate which performs a router redirect, but doesn't block the route change (i.e. it always resolves to true).

    @Injectable()
    export class CanActivateStart implements CanActivate {
        public constructor(private _router: Router) {
    
        }
    
        public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
            if(!(route.component instanceof StartComponent)) {
               this._router.navigateByUrl('/start'); 
            }
            return true;
        }
    
    }
    

    It might look strange to always return true, but if you return false it cancels the route change and at the sametime blocks the navigateByUrl().

    Place this at the top level of the router configuration, and it will only be executed once. When the browser is refreshed it will trigger the redirect.

    const routes = [
         {
            canActivate: [CanActivateStart],
            children: [
               // the routes you want to force a redirect
            ]
         }, {....}
    ]