RouterListener

Event-driven listener for Angular Router's navigation lifecycle and events. Subscribe to specific router events with type-safe handlers.

Usage

angular-ts
import { Component } from '@angular/core';
import { routerListener } from '@signality/core';

@Component({
  template: `<router-outlet />`,
})
export class App {
  constructor() {
    routerListener('navigationstart', event => {
      console.log('Navigation started:', event.url); 
    });
  }
}

Parameters

ParameterTypeDescription
eventRouterEventType | readonly RouterEventType[]Router event name(s) in lowercase. Can be a single event or an array of events (see Supported Events below)
handler(event: EventType) => voidType-safe handler function. For single event, receives the specific event type. For array of events, receives a union type of all events
optionsRouterListenerOptionsOptional configuration (see Options below)

Options

The RouterListenerOptions extends WithInjector:

OptionTypeDefaultDescription
oncebooleanfalseIf true, automatically unsubscribe after the first event
injectorInjector-Optional injector for DI context

Return Value

Returns a RouterListenerRef object with the following method:

PropertyTypeDescription
destroy() => voidManually unsubscribe from router events

Supported Events

All Angular Router events are supported. Event names are in lowercase (camelCase):

Event TypeEvent ClassDescription
navigationstartNavigationStartOccurs when navigation starts
navigationendNavigationEndOccurs when navigation ends successfully
navigationcancelNavigationCancelOccurs when navigation is cancelled
navigationerrorNavigationErrorOccurs when navigation fails
navigationskippedNavigationSkippedOccurs when navigation is skipped
routesrecognizedRoutesRecognizedOccurs when routes are recognized
guardscheckstartGuardsCheckStartOccurs at the start of guard phase
guardscheckendGuardsCheckEndOccurs at the end of guard phase
resolvestartResolveStartOccurs at the start of resolve phase
resolveendResolveEndOccurs at the end of resolve phase
routeconfigloadstartRouteConfigLoadStartOccurs before lazy loading route configuration
routeconfigloadendRouteConfigLoadEndOccurs after lazy-loaded route configuration loads
childactivationstartChildActivationStartOccurs at the start of child route activation
childactivationendChildActivationEndOccurs at the end of child route activation
activationstartActivationStartOccurs at the start of route activation
activationendActivationEndOccurs at the end of route activation
scrollScrollOccurs during scrolling

Examples

Loading indicator

angular-ts
import { Component, signal } from '@angular/core';
import { routerListener } from '@signality/core';

@Component({
  selector: 'app-root',
  template: `
    @if (isLoading()) {
      <div class="loading-bar">Loading...</div>
    }
    <router-outlet />
  `,
})
export class App {
  readonly isLoading = signal(false);

  constructor() {
    routerListener('navigationstart', () => {
      this.isLoading.set(true);
    });

    // Using array of events
    routerListener(['navigationend', 'navigationerror'], () => {
      this.isLoading.set(false);
    });
  }
}

Analytics tracking

angular-ts
import { Component, inject } from '@angular/core';
import { routerListener } from '@signality/core';
import { AnalyticsService } from './analytics.service';

@Component({ /* ... */ })
export class App {
  private analytics = inject(AnalyticsService);

  constructor() {
    routerListener('navigationend', event => {
      this.analytics.trackPageView(event.urlAfterRedirects); 
    });
  }
}

Error handling

angular-ts
import { Component, signal } from '@angular/core';
import { routerListener } from '@signality/core';

@Component({
  template: `
    @if (error(); as error) {
      <div class="error-banner">
        <p>Navigation error: {{ error.message }}</p>
        <button (click)="dismissError()">Dismiss</button>
      </div>
    }
    <router-outlet />
  `,
})
export class App {
  readonly error = signal<Error | null>(null);

  constructor() {
    routerListener('navigationerror', event => {
      this.error.set(event.error); 
    });
  }

  dismissError() {
    this.error.set(null);
  }
}

Guard rejection tracking

angular-ts
import { Component } from '@angular/core';
import { routerListener } from '@signality/core';

@Component({ /* ... */ })
export class App {
  constructor() {
    routerListener('navigationcancel', event => {
      if (event.code === NavigationCancellationCode.GuardRejected) {
        console.warn('Navigation cancelled by guard:', event.reason);
      }
    });
  }
}

Route resolution tracking

angular-ts
import { Component } from '@angular/core';
import { routerListener } from '@signality/core';

@Component({ /* ... */ })
export class App {
  constructor() {
    routerListener('resolvestart', event => {
      console.log('Resolving data for:', event.urlAfterRedirects);
    });

    routerListener('resolveend', event => {
      console.log('Data resolved for:', event.urlAfterRedirects);
    });
  }
}

One-time listener

angular-ts
import { Component } from '@angular/core';
import { routerListener } from '@signality/core';

@Component({ /* ... */ })
export class App {
  constructor() {
    // Automatically unsubscribe after first navigation
    routerListener('navigationstart', event => {
      console.log('First navigation:', event.url);
    }, { once: true }); 
  }
}

Type Definitions

typescript
type RouterEventType =
  | 'navigationstart'
  | 'navigationend'
  | 'navigationcancel'
  | 'navigationerror'
  | 'navigationskipped'
  | 'routesrecognized'
  | 'guardscheckstart'
  | 'guardscheckend'
  | 'resolvestart'
  | 'resolveend'
  | 'routeconfigloadstart'
  | 'routeconfigloadend'
  | 'childactivationstart'
  | 'childactivationend'
  | 'activationstart'
  | 'activationend'
  | 'scroll';

interface RouterListenerOptions extends WithInjector {
  /** If true, automatically unsubscribe after the first event */
  readonly once?: boolean;
}

interface RouterListenerRef {
  /** Manually unsubscribe from router events */
  readonly destroy: () => void;
}

// Overloads for type-safe handlers (single event)
function routerListener(
  event: 'navigationstart',
  handler: (event: NavigationStart) => void,
  options?: RouterListenerOptions
): RouterListenerRef;
// ... (overloads for all event types)

// Overload for multiple events with union type
function routerListener<T extends readonly [RouterEventType, ...RouterEventType[]]>(
  events: T,
  handler: (event: RouterEventTypeArrayToUnion<T>) => void,
  options?: RouterListenerOptions
): RouterListenerRef;
Edit this page on GitHub Last updated: Mar 19, 2026, 23:28:23