Angular2 router keep query string

I wrote an Angular2 (v2.0.1) application that makes use of the router. The website is loaded with several query string parameters, so the full URL initially looks like this:

https://my.application.com/?param1=val1&param2=val2&param3=val3

In my route configuration, I have an entry which redirects an empty route:

const appRoutes: Routes = [
    {
        path: '',
        redirectTo: '/comp1',
        pathMatch: 'full'
    },
    {
        path: 'comp1',
        component: FirstComponent
    },
    {
        path: 'comp2',
        component: SecondComponent
    }
];

My problem is, that after the app has been bootstrapped, the URL does not contain the query parameters anymore, instead it looks like this:

https://my.application.com/comp1

Is there any way I can configure the router so that it keeps the initial query string when navigating?

Thank you
Lukas


I don't think there is a way to define that in the routes configuration.

Currently it is supported for routerLinks and imperative navigation to enable

  • preserveQueryParams and
  • preserveFragment

You can add a guard to the empty path route, where in the guard navigation to the /comp1 route is done.

router.navigate(['/comp1'], { preserveQueryParams: true }); //deprecated. see update note
router.navigate(['/comp1'], { queryParamsHandling: "merge" });

There is a PR to allow to configure preserveQueryParams globally.

Update note: from https://angular.io/api/router/NavigationExtras, preserveQueryParams is deprecated, use queryParamsHandling instead


If you are navigating using HTML template then you can use

<a [routerLink]="['/page-2']" [routerLinkActive]="['is-active']" queryParamsHandling="merge">

Something to watch out for is that queryParamsHandling param is without the square brackets.


It turns out the undocumented way to do this without other hacks is to simply remove the leading slash in the "redirectTo" field. Since you are matching the full path you can have the certainty that it'll do what you want (i.e. no surprise url segments) and since it's no longer an absolute target, Angular will preserve the current query parameters.

So in this case

{
  path: '',
  redirectTo: '/comp1',
  pathMatch: 'full'
}

becomes:

{
  path: '',
  redirectTo: 'comp1',
  pathMatch: 'full'
}

Source: https://github.com/angular/angular/issues/13315


Günter Zöchbauer's answer should work properly but, for some reason, it is not working for me at all. What did end up working was passing the queryParams directly instead of 'preserving' them.

This is what my guard looks like:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    (...)
    this.router.navigate(['login'], { queryParams: route.queryParams });
}