Back to Angular

Router Lifecycle and Events

adev/src/content/guide/routing/lifecycle-and-events.md

22.0.0-next.1011.5 KB
Original Source

Router Lifecycle and Events

Angular Router provides a comprehensive set of lifecycle hooks and events that allow you to respond to navigation changes and execute custom logic during the routing process.

Common router events

The Angular Router emits navigation events that you can subscribe to in order to track the navigation lifecycle. These events are available through the Router.events observable. This section covers common routing lifecycle events for navigation and error tracking (in chronological order).

EventsDescription
NavigationStartOccurs when navigation begins and contains the requested URL.
RoutesRecognizedOccurs after the router determines which route matches the URL and contains the route state information.
GuardsCheckStartBegins the route guard phase. The router evaluates route guards like canActivate and canDeactivate.
GuardsCheckEndSignals completion of guard evaluation. Contains the result (allowed/denied).
ResolveStartBegins the data resolution phase. Route resolvers start fetching data.
ResolveEndData resolution completes. All required data becomes available.
NavigationEndFinal event when navigation completes successfully. The router updates the URL.
NavigationSkippedOccurs when the router skips navigation (e.g., same URL navigation).

The following are common error events:

EventDescription
NavigationCancelOccurs when the router cancels navigation. Often due to a guard returning false.
NavigationErrorOccurs when navigation fails. Could be due to invalid routes or resolver errors.

For a list of all lifecycle events, check out the complete table of this guide.

How to subscribe to router events

When you want to run code during specific navigation lifecycle events, you can do so by subscribing to the router.events and checking the instance of the event:

ts
// Example of subscribing to router events
import {Component, inject, signal, effect} from '@angular/core';
import {Event, Router, NavigationStart, NavigationEnd} from '@angular/router';

@Component({
  /*...*/
})
export class RouterEvents {
  private readonly router = inject(Router);

  constructor() {
    // Subscribe to router events and react to events
    this.router.events.pipe(takeUntilDestroyed()).subscribe((event: Event) => {
      if (event instanceof NavigationStart) {
        // Navigation starting
        console.log('Navigation starting:', event.url);
      }
      if (event instanceof NavigationEnd) {
        // Navigation completed
        console.log('Navigation completed:', event.url);
      }
    });
  }
}

NOTE: The Event type from @angular/router is named the same as the regular global Event type, but it is different from the RouterEvent type.

How to debug routing events

Debugging router navigation issues can be challenging without visibility into the event sequence. Angular provides a built-in debugging feature that logs all router events to the console, helping you understand the navigation flow and identify where issues occur.

When you need to inspect a Router event sequence, you can enable logging for internal navigation events for debugging. You can configure this by passing a configuration option (withDebugTracing()) that enables detailed console logging of all routing events.

ts
import {provideRouter, withDebugTracing} from '@angular/router';

const appRoutes: Routes = [];
bootstrapApplication(App, {
  providers: [provideRouter(appRoutes, withDebugTracing())],
});

For more information, check out the official docs on withDebugTracing.

Common use cases

Router events enable many practical features in real-world applications. Here are some common patterns that are used with router events.

Loading indicators

Show loading indicators during navigation:

angular-ts
import {Component, inject} from '@angular/core';
import {Router} from '@angular/router';

@Component({
  selector: 'app-root',
  template: `
    @if (isNavigating()) {
      <div class="loading-bar">Loading...</div>
    }
    <router-outlet />
  `,
})
export class App {
  private router = inject(Router);
  isNavigating = computed(() => !!this.router.currentNavigation());
}

Analytics tracking

Track page views for analytics:

ts
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {inject, Injectable, DestroyRef} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router';

@Injectable({providedIn: 'root'})
export class AnalyticsService {
  private router = inject(Router);
  private destroyRef = inject(DestroyRef);

  startTracking() {
    this.router.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
      // Track page views when URL changes
      if (event instanceof NavigationEnd) {
        // Send page view to analytics
        this.analytics.trackPageView(event.url);
      }
    });
  }

  private analytics = {
    trackPageView: (url: string) => {
      console.log('Page view tracked:', url);
    },
  };
}

Error handling

Handle navigation errors gracefully and provide user feedback:

angular-ts
import {Component, inject, signal} from '@angular/core';
import {
  Router,
  NavigationStart,
  NavigationError,
  NavigationCancel,
  NavigationCancellationCode,
} from '@angular/router';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-error-handler',
  template: `
    @if (errorMessage()) {
      <div class="error-banner">
        {{ errorMessage() }}
        <button (click)="dismissError()">Dismiss</button>
      </div>
    }
  `,
})
export class ErrorHandler {
  private router = inject(Router);
  readonly errorMessage = signal('');

  constructor() {
    this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {
      if (event instanceof NavigationStart) {
        this.errorMessage.set('');
      } else if (event instanceof NavigationError) {
        console.error('Navigation error:', event.error);
        this.errorMessage.set('Failed to load page. Please try again.');
      } else if (event instanceof NavigationCancel) {
        console.warn('Navigation cancelled:', event.reason);
        if (event.code === NavigationCancellationCode.GuardRejected) {
          this.errorMessage.set('Access denied. Please check your permissions.');
        }
      }
    });
  }

  dismissError() {
    this.errorMessage.set('');
  }
}

All router events

For reference, here is the complete list of all router events available in Angular. These events are organized by category and listed in the order they typically occur during navigation.

These events track the core navigation process from start through route recognition, guard checks, and data resolution. They provide visibility into each phase of the navigation lifecycle.

EventDescription
NavigationStartOccurs when navigation starts
RouteConfigLoadStartOccurs before lazy loading a route configuration
RouteConfigLoadEndOccurs after a lazy-loaded route configuration loads
RoutesRecognizedOccurs when the router parses the URL and recognizes the routes
GuardsCheckStartOccurs at the start of the guard phase
GuardsCheckEndOccurs at the end of the guard phase
ResolveStartOccurs at the start of the resolve phase
ResolveEndOccurs at the end of the resolve phase

Activation events

These events occur during the activation phase when route components are being instantiated and initialized. Activation events fire for each route in the route tree, including parent and child routes.

EventDescription
ActivationStartOccurs at the start of route activation
ChildActivationStartOccurs at the start of child route activation
ActivationEndOccurs at the end of route activation
ChildActivationEndOccurs at the end of child route activation

These events represent the final outcome of a navigation attempt. Every navigation will end with exactly one of these events, indicating whether it succeeded, was cancelled, failed, or was skipped.

EventDescription
NavigationEndOccurs when navigation ends successfully
NavigationCancelOccurs when the router cancels navigation
NavigationErrorOccurs when navigation fails due to an unexpected error
NavigationSkippedOccurs when the router skips navigation (e.g., same URL navigation)

Other events

There is one additional event that occurs outside the main navigation lifecycle, but it is still part of the router's event system.

EventDescription
ScrollOccurs during scrolling

Next steps

Learn more about route guards and common router tasks.