|
| 1 | +# Router Lifecycle and Events |
| 2 | + |
| 3 | +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. |
| 4 | + |
| 5 | +## Common router events |
| 6 | + |
| 7 | +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). |
| 8 | + |
| 9 | +| Events | Description | |
| 10 | +| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | |
| 11 | +| [`NavigationStart`](api/router/NavigationStart) | Occurs when navigation begins and contains the requested URL. | |
| 12 | +| [`RoutesRecognized`](api/router/RoutesRecognized) | Occurs after the router determines which route matches the URL and contains the route state information. | |
| 13 | +| [`GuardsCheckStart`](api/router/GuardsCheckStart) | Begins the route guard phase. The router evaluates route guards like `canActivate` and `canDeactivate`. | |
| 14 | +| [`GuardsCheckEnd`](api/router/GuardsCheckEnd) | Signals completion of guard evaluation. Contains the result (allowed/denied). | |
| 15 | +| [`ResolveStart`](api/router/ResolveStart) | Begins the data resolution phase. Route resolvers start fetching data. | |
| 16 | +| [`ResolveEnd`](api/router/ResolveEnd) | Data resolution completes. All required data becomes available. | |
| 17 | +| [`NavigationEnd`](api/router/NavigationEnd) | Final event when navigation completes successfully. The router updates the URL. | |
| 18 | +| [`NavigationSkipped`](api/router/NavigationSkipped) | Occurs when the router skips navigation (e.g., same URL navigation). | |
| 19 | + |
| 20 | +The following are common error events: |
| 21 | + |
| 22 | +| Event | Description | |
| 23 | +| ------------------------------------------------- | -------------------------------------------------------------------------------- | |
| 24 | +| [`NavigationCancel`](api/router/NavigationCancel) | Occurs when the router cancels navigation. Often due to a guard returning false. | |
| 25 | +| [`NavigationError`](api/router/NavigationError) | Occurs when navigation fails. Could be due to invalid routes or resolver errors. | |
| 26 | + |
| 27 | +For a list of all lifecycle events, check out the [complete table of this guide](#all-router-events). |
| 28 | + |
| 29 | +## How to subscribe to router events |
| 30 | + |
| 31 | +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: |
| 32 | + |
| 33 | +```ts |
| 34 | +// Example of subscribing to router events |
| 35 | +import { Component, inject, signal, effect } from '@angular/core'; |
| 36 | +import { Event, Router, NavigationStart, NavigationEnd } from '@angular/router'; |
| 37 | + |
| 38 | +@Component({ ... }) |
| 39 | +export class RouterEventsComponent { |
| 40 | + private readonly router = inject(Router); |
| 41 | + |
| 42 | + constructor() { |
| 43 | + // Subscribe to router events and react to events |
| 44 | + this.router.events.pipe(takeUntilDestroyed()).subscribe((event: Event) => { |
| 45 | + if (event instanceof NavigationStart) { |
| 46 | + // Navigation starting |
| 47 | + console.log('Navigation starting:', event.url); |
| 48 | + } |
| 49 | + if (event instanceof NavigationEnd) { |
| 50 | + // Navigation completed |
| 51 | + console.log('Navigation completed:', event.url); |
| 52 | + } |
| 53 | + }); |
| 54 | + } |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +Note: The [`Event`](api/router/Event) type from `@angular/router` is named the same as the regular global [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event) type, but it is different from the [`RouterEvent`](api/router/RouterEvent) type. |
| 59 | + |
| 60 | +## How to debug routing events |
| 61 | + |
| 62 | +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. |
| 63 | + |
| 64 | +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. |
| 65 | + |
| 66 | +```ts |
| 67 | +import { provideRouter, withDebugTracing } from '@angular/router'; |
| 68 | + |
| 69 | +const appRoutes: Routes = []; |
| 70 | +bootstrapApplication(AppComponent, |
| 71 | + { |
| 72 | + providers: [ |
| 73 | + provideRouter(appRoutes, withDebugTracing()) |
| 74 | + ] |
| 75 | + } |
| 76 | +); |
| 77 | +``` |
| 78 | + |
| 79 | +For more information, check out the official docs on [`withDebugTracing`](api/router/withDebugTracing). |
| 80 | + |
| 81 | +## Common use cases |
| 82 | + |
| 83 | +Router events enable many practical features in real-world applications. Here are some common patterns that are used with router events. |
| 84 | + |
| 85 | +### Loading indicators |
| 86 | + |
| 87 | +Show loading indicators during navigation: |
| 88 | + |
| 89 | +```angular-ts |
| 90 | +import { Component, inject } from '@angular/core'; |
| 91 | +import { Router } from '@angular/router'; |
| 92 | +import { toSignal } from '@angular/core/rxjs-interop'; |
| 93 | +import { map } from 'rxjs/operators'; |
| 94 | +
|
| 95 | +@Component({ |
| 96 | + selector: 'app-loading', |
| 97 | + template: ` |
| 98 | + @if (loading()) { |
| 99 | + <div class="loading-spinner">Loading...</div> |
| 100 | + } |
| 101 | + ` |
| 102 | +}) |
| 103 | +export class AppComponent { |
| 104 | + private router = inject(Router); |
| 105 | + |
| 106 | + readonly loading = toSignal( |
| 107 | + this.router.events.pipe( |
| 108 | + map(() => !!this.router.getCurrentNavigation()) |
| 109 | + ), |
| 110 | + { initialValue: false } |
| 111 | + ); |
| 112 | +} |
| 113 | +``` |
| 114 | + |
| 115 | +### Analytics tracking |
| 116 | + |
| 117 | +Track page views for analytics: |
| 118 | + |
| 119 | +```typescript |
| 120 | +import { Component, inject, signal, effect } from '@angular/core'; |
| 121 | +import { Router, NavigationEnd } from '@angular/router'; |
| 122 | + |
| 123 | +@Injectable({ providedIn: 'root' }) |
| 124 | +export class AnalyticsService { |
| 125 | + private router = inject(Router); |
| 126 | + private destroyRef = inject(DestroyRef); |
| 127 | + |
| 128 | + startTracking() { |
| 129 | + this.router.events.pipe(takeUntilDestroyed(this.destroyRef)) |
| 130 | + .subscribe(event => { |
| 131 | + // Track page views when URL changes |
| 132 | + if (event instanceof NavigationEnd) { |
| 133 | + // Send page view to analytics |
| 134 | + this.analytics.trackPageView(url); |
| 135 | + } |
| 136 | + }); |
| 137 | + } |
| 138 | + |
| 139 | + private analytics = { |
| 140 | + trackPageView: (url: string) => { |
| 141 | + console.log('Page view tracked:', url); |
| 142 | + } |
| 143 | + }; |
| 144 | +} |
| 145 | +``` |
| 146 | + |
| 147 | +### Error handling |
| 148 | + |
| 149 | +Handle navigation errors gracefully and provide user feedback: |
| 150 | + |
| 151 | +```angular-ts |
| 152 | +import { Component, inject, signal } from '@angular/core'; |
| 153 | +import { Router, NavigationStart, NavigationError, NavigationCancel, NavigationCancellationCode } from '@angular/router'; |
| 154 | +
|
| 155 | +@Component({ |
| 156 | + selector: 'app-error-handler', |
| 157 | + template: ` |
| 158 | + @if (errorMessage()) { |
| 159 | + <div class="error-banner"> |
| 160 | + {{ errorMessage() }} |
| 161 | + <button (click)="dismissError()">Dismiss</button> |
| 162 | + </div> |
| 163 | + } |
| 164 | + ` |
| 165 | +}) |
| 166 | +export class ErrorHandlerComponent { |
| 167 | + private router = inject(Router); |
| 168 | + readonly errorMessage = signal(''); |
| 169 | +
|
| 170 | + constructor() { |
| 171 | + this.router.events.pipe(takeUntilDestroyed()).subscribe(event => { |
| 172 | + if (event instanceof NavigationStart) { |
| 173 | + this.errorMessage.set(''); |
| 174 | + } else if (event instanceof NavigationError) { |
| 175 | + console.error('Navigation error:', event.error); |
| 176 | + this.errorMessage.set('Failed to load page. Please try again.'); |
| 177 | + } else if (event instanceof NavigationCancel) { |
| 178 | + console.warn('Navigation cancelled:', event.reason); |
| 179 | + if (event.reason === NavigationCancellationCode.GuardRejected) { |
| 180 | + this.errorMessage.set('Access denied. Please check your permissions.'); |
| 181 | + } |
| 182 | + } |
| 183 | + }); |
| 184 | + } |
| 185 | +
|
| 186 | + dismissError() { |
| 187 | + this.errorMessage.set(''); |
| 188 | + } |
| 189 | +} |
| 190 | +``` |
| 191 | + |
| 192 | +## All router events |
| 193 | + |
| 194 | +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. |
| 195 | + |
| 196 | +### Navigation events |
| 197 | + |
| 198 | +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. |
| 199 | + |
| 200 | +| Event | Description | |
| 201 | +| --------------------------------------------------------- | --------------------------------------------------------------- | |
| 202 | +| [`NavigationStart`](api/router/NavigationStart) | Occurs when navigation starts | |
| 203 | +| [`RouteConfigLoadStart`](api/router/RouteConfigLoadStart) | Occurs before lazy loading a route configuration | |
| 204 | +| [`RouteConfigLoadEnd`](api/router/RouteConfigLoadEnd) | Occurs after a lazy-loaded route configuration loads | |
| 205 | +| [`RoutesRecognized`](api/router/RoutesRecognized) | Occurs when the router parses the URL and recognizes the routes | |
| 206 | +| [`GuardsCheckStart`](api/router/GuardsCheckStart) | Occurs at the start of the guard phase | |
| 207 | +| [`GuardsCheckEnd`](api/router/GuardsCheckEnd) | Occurs at the end of the guard phase | |
| 208 | +| [`ResolveStart`](api/router/ResolveStart) | Occurs at the start of the resolve phase | |
| 209 | +| [`ResolveEnd`](api/router/ResolveEnd) | Occurs at the end of the resolve phase | |
| 210 | + |
| 211 | +### Activation events |
| 212 | + |
| 213 | +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. |
| 214 | + |
| 215 | +| Event | Description | |
| 216 | +| --------------------------------------------------------- | --------------------------------------------- | |
| 217 | +| [`ActivationStart`](api/router/ActivationStart) | Occurs at the start of route activation | |
| 218 | +| [`ChildActivationStart`](api/router/ChildActivationStart) | Occurs at the start of child route activation | |
| 219 | +| [`ActivationEnd`](api/router/ActivationEnd) | Occurs at the end of route activation | |
| 220 | +| [`ChildActivationEnd`](api/router/ChildActivationEnd) | Occurs at the end of child route activation | |
| 221 | + |
| 222 | +### Navigation completion events |
| 223 | + |
| 224 | +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. |
| 225 | + |
| 226 | +| Event | Description | |
| 227 | +| --------------------------------------------------- | ------------------------------------------------------------------- | |
| 228 | +| [`NavigationEnd`](api/router/NavigationEnd) | Occurs when navigation ends successfully | |
| 229 | +| [`NavigationCancel`](api/router/NavigationCancel) | Occurs when the router cancels navigation | |
| 230 | +| [`NavigationError`](api/router/NavigationError) | Occurs when navigation fails due to an unexpected error | |
| 231 | +| [`NavigationSkipped`](api/router/NavigationSkipped) | Occurs when the router skips navigation (e.g., same URL navigation) | |
| 232 | + |
| 233 | +### Other events |
| 234 | + |
| 235 | +There is one additional event that occurs outside the main navigation lifecycle, but it is still part of the router's event system. |
| 236 | + |
| 237 | +| Event | Description | |
| 238 | +| ----------------------------- | ----------------------- | |
| 239 | +| [`Scroll`](api/router/Scroll) | Occurs during scrolling | |
| 240 | + |
| 241 | +## Next steps |
| 242 | + |
| 243 | +Learn more about [route guards](/guide/routing/route-guards) and [common router tasks](/guide/routing/common-router-tasks). |
0 commit comments