NgRx Angular Router Router Store
The NgRx Router Store integrates the Angular Router state into the global NgRx Store. This lets you select, react to, and test routing information (URL, params, query params, etc.) in a fully reactive way, instead of reaching for ActivatedRoute in every component.
By mirroring the router tree into the store, you can combine routing data with other feature states, drive navigation from Effects, and keep your application routing logic predictable and testable.
router).StoreRouterConnectingModule – Connects Angular Router with NgRx Store.RouterReducerState – Describes the shape of the router slice held in the store.url, route params, and query params reactively.To enable Router Store, you need to:
StoreModule.forRoot().StoreRouterConnectingModule.forRoot() in your root module.
// app.module.ts - configure NgRx Router Store
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from '@ngrx/store';
import { StoreRouterConnectingModule } from '@ngrx/router-store';
import { AppComponent } from './app.component';
import { reducers } from './reducers';
@NgModule({
imports: [
BrowserModule,
StoreModule.forRoot(reducers),
StoreRouterConnectingModule.forRoot()
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
Once Router Store is connected, the router slice is usually available as state.router. You can create selectors to expose exactly the data your components need (e.g., current URL, route params, or query params).
// selectors/router.selectors.ts - select current URL from Router Store
import { createSelector } from '@ngrx/store';
import { RouterReducerState } from '@ngrx/router-store';
export const selectRouter = (state: any) => state.router;
export const selectCurrentUrl = createSelector(
selectRouter,
(router: RouterReducerState<any>) => router?.state?.url
);
You can build more advanced selectors for route params:
// selectors/router.selectors.ts - select route param "id"
import { createSelector } from '@ngrx/store';
import { RouterReducerState } from '@ngrx/router-store';
export const selectRouter = (state: any) => state.router;
export const selectRouteParams = createSelector(
selectRouter,
(router: RouterReducerState<any>) => router?.state?.params
);
export const selectRouteId = createSelector(
selectRouteParams,
params => params?.['id']
);
Components subscribe to router selectors through the Store. Because selectors return observables, the template can use the async pipe to render the latest router values.
// app.component.ts - display current URL from Router Store
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { selectCurrentUrl } from './selectors/router.selectors';
@Component({
selector: 'app-root',
template: `<p>Current URL: {{ url$ | async }}</p>`
})
export class AppComponent {
url$: Observable<string | undefined>;
constructor(private store: Store) {
this.url$ = this.store.select(selectCurrentUrl);
}
}
When the application starts and the user navigates to /products/42?sort=price, the selector returns that URL.
The template renders something like:
Current URL: /products/42?sort=price
As the user navigates, the observable emits new values, and the text updates automatically without manual subscriptions or cleanup.
selectRouteId) with entity selectors to fetch entities by ID directly from the store.id) and use it to select an entity from your NgRx Entity state by that ID.async pipe./success page using the router.