An extension to @ngrx/router-store providing router serialization and a navigation action. Making it time-travel compatible.
Switch branches/tags
Nothing to show
Clone or download


An (sort of) extension to @ngrx/router-store providing router serialization and a navigation action. This allows for ReduxDevTools time travel to work.


On your project folder:

npm install router-store-ser --save


Import the module

Import the RouterStoreSerModule into your app module:

import { RouterStoreSerModule } from 'router-store-ser';

    imports: [

Note that RouterStoreSerModule depends on @ngrx/router-store wich depends on the Store module from @ngrx/store. Also the RouterStoreSerModule declares an EffectsModule.forChild() so there must be a .forRoot().

At this point, the action ROUTER_NAVIGATION of @ngrx/router-store now has the payload simplified (comparing to its default implementation):

    payload: {
        routerState: {
            url: '/start',
            root: {
                configPath: 'start',
                data: {
                    uid: '3e412cfd-a338-4b6a-ac88-9a41fb700f73'
                params: {},
                children: [ ]
        event: ...

This routerState serialization can be extended by creating a new class that extends this module's RouterStateSerializer and providing it.

Configure the Routes

Mark configured routes needed to be later referred to with some (app wide unique) id:

export const startRouteId = '3e412cfd-a338-4b6a-ac88-9a41fb700f73';
export const endRouteId = '352951ae-8057-4d39-81d1-d46ab3b9c5bd';

const appRoutes: Routes = [
        path: 'start',
        component: StartContainer,
        data: {
            uid: startRouteId,
        path: 'end',
        component: EndContainer;
        data: {
            uid: endRouteId

The parameter name "uid" can be customize by providing a string with DataPropertyToken:

import { DataPropertyToken } from 'router-state-serializer';

    providers: [
        { provide: DataPropertyToken, useValue: 'myid' }

At this point, the routes can be searched using the action payload. The following example is an effect that make the app navigate apon detecting a ROUTER_NAVIGATION action for some specific route:

import { ROUTER_NAVIGATION, RouterNavigationAction, RouterStateSerializer } from '@ngrx/router-store';
import { RouterStateSerializer as CustomRouterStateSerializer, RouterStateSer, NavigationGoAction } from 'router-store-ser';

import { startRouteId } from './app-routing.module';

export class StartEffects
    public effect$: Observable<Action>;

        protected actions$: Actions,
        protected routerStateSerializer: CustomRouterStateSerializer
        this.effect$ = this.actions$.ofType<RouterNavigationAction<RouterStateSer>>(ROUTER_NAVIGATION)
            .filter(action => !!this.routerStateSerializer.findNodeById(
                action.payload.routerState.root, startRouteId))
            .map(action =>
                return new NavigationGoAction({
                    commands: ['../continue'],
                    relativeRouteId: startRouteId

There is also available a function to search an Angular ActivatedRoute for a route with a specified id:

this.routerStateSerializer.findRouteById(this.router.routerState.root, startRouteId)

Dispatching a NavigationGoAction

This action make the Angular router to navigate. Check Router.navigate() reference on Angular docs. This way app navigation can be accomplished in effects.

This example acomplishes a relative navigation, referring to the configured route with the specified id: NavigationGoAction({
    commands: ['../question', 1],
    relativeRouteId: startRouteId


Contributions and issues are welcome.

Testing and linting scripts are provided:

npm run test

npm run lint