The Angular Router enables navigation from one view to the next as users perform tasks in your application. It interprets browser URL changes as instructions to navigate to a client-generated view and can pass optional parameters to the view component.
What is the Router?
The Angular Router is a core service that:
Maps URL paths to components
Manages browser history and navigation
Handles route parameters and query parameters
Supports lazy loading of feature modules
Provides navigation guards for access control
Resolves data before route activation
Router Setup
There are two ways to configure the router in Angular: using provideRouter (standalone) or RouterModule (module-based).
Standalone Setup (Recommended)
The modern approach uses provideRouter with the standalone API:
import { bootstrapApplication } from '@angular/platform-browser' ;
import { provideRouter } from '@angular/router' ;
import { AppComponent } from './app/app.component' ;
import { routes } from './app/app.routes' ;
bootstrapApplication ( AppComponent , {
providers: [
provideRouter ( routes )
]
});
The provideRouter function is defined in packages/router/src/provide_router.ts:99 and sets up all necessary router services.
Module-Based Setup
For applications using NgModules:
import { NgModule } from '@angular/core' ;
import { RouterModule , Routes } from '@angular/router' ;
import { BrowserModule } from '@angular/platform-browser' ;
import { AppComponent } from './app.component' ;
const routes : Routes = [
// Route definitions
];
@ NgModule ({
imports: [
BrowserModule ,
RouterModule . forRoot ( routes )
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
Use RouterModule.forRoot() only in the root module. For feature modules, use RouterModule.forChild() instead.
Router Configuration Options
You can customize router behavior with additional features:
import {
provideRouter ,
withDebugTracing ,
withRouterConfig ,
withComponentInputBinding ,
withViewTransitions
} from '@angular/router' ;
bootstrapApplication ( AppComponent , {
providers: [
provideRouter (
routes ,
withDebugTracing (), // Log navigation events to console
withRouterConfig ({
paramsInheritanceStrategy: 'always' ,
onSameUrlNavigation: 'reload'
}),
withComponentInputBinding (), // Bind route data to component inputs
withViewTransitions () // Enable view transitions API
)
]
});
The Router Service
The Router service provides methods for programmatic navigation:
import { Component , inject } from '@angular/core' ;
import { Router } from '@angular/router' ;
@ Component ({
selector: 'app-navigation' ,
template: `
<button (click)="navigateToUser()">Go to User</button>
`
})
export class NavigationComponent {
private router = inject ( Router );
navigateToUser () {
// Navigate using an array of commands
this . router . navigate ([ '/user' , 123 ]);
}
navigateWithQueryParams () {
// Navigate with query parameters
this . router . navigate ([ '/search' ], {
queryParams: { q: 'angular' },
fragment: 'results'
});
}
navigateByUrl () {
// Navigate using a URL string
this . router . navigateByUrl ( '/dashboard' );
}
}
Router Properties
The Router service exposes several useful properties:
// Current router state tree
const state : RouterState = router . routerState ;
// Current URL as a UrlTree
const url : UrlTree = router . url ;
// Observable of navigation events
router . events . subscribe ( event => {
if ( event instanceof NavigationEnd ) {
console . log ( 'Navigation completed:' , event . url );
}
});
// Current navigation (signal)
const currentNav = router . currentNavigation ();
// Check if any navigation has occurred
const hasNavigated : boolean = router . navigated ;
Router Outlet
The <router-outlet> directive marks where the router should display views:
< nav >
< a routerLink = "/home" > Home </ a >
< a routerLink = "/about" > About </ a >
</ nav >
< router-outlet ></ router-outlet >
Named Outlets
You can use multiple outlets to display different content simultaneously:
< router-outlet ></ router-outlet > <!-- Primary outlet -->
< router-outlet name = "sidebar" ></ router-outlet > <!-- Named outlet -->
const routes : Routes = [
{
path: 'home' ,
component: HomeComponent
},
{
path: 'chat' ,
component: ChatComponent ,
outlet: 'sidebar' // Displays in named outlet
}
];
RouterLink Directive
The routerLink directive creates navigation links:
<!-- Simple static link -->
< a routerLink = "/about" > About </ a >
<!-- Link with parameter -->
< a [routerLink] = "['/user', userId]" > User Profile </ a >
<!-- Link with query params and fragment -->
< a [routerLink] = "['/products']"
[queryParams] = "{category: 'electronics'}"
[fragment] = "'reviews'" >
Electronics
</ a >
<!-- Relative navigation -->
< a routerLink = "../sibling" > Sibling Route </ a >
< a routerLink = "./child" > Child Route </ a >
RouterLinkActive
Highlight active links automatically:
< nav >
< a routerLink = "/home"
routerLinkActive = "active"
[routerLinkActiveOptions] = "{exact: true}" >
Home
</ a >
< a routerLink = "/about"
routerLinkActive = "active" >
About
</ a >
</ nav >
.active {
font-weight : bold ;
color : #007bff ;
border-bottom : 2 px solid #007bff ;
}
Navigation Events
The router emits events during navigation:
import { Router , NavigationStart , NavigationEnd , NavigationError } from '@angular/router' ;
import { filter } from 'rxjs/operators' ;
export class AppComponent {
private router = inject ( Router );
ngOnInit () {
this . router . events . pipe (
filter ( event =>
event instanceof NavigationStart ||
event instanceof NavigationEnd ||
event instanceof NavigationError
)
). subscribe ( event => {
if ( event instanceof NavigationStart ) {
console . log ( 'Navigation started:' , event . url );
} else if ( event instanceof NavigationEnd ) {
console . log ( 'Navigation completed:' , event . url );
} else if ( event instanceof NavigationError ) {
console . error ( 'Navigation error:' , event . error );
}
});
}
}
Navigation events are defined in packages/router/src/events.ts and include NavigationStart, NavigationEnd, NavigationCancel, NavigationError, RoutesRecognized, and more.
Best Practices
Use provideRouter Prefer the standalone provideRouter API for new applications. It’s more modern and tree-shakeable.
Lazy Load Modules Use lazy loading for feature modules to reduce initial bundle size and improve load times.
Type-Safe Routes Define routes in a separate file and export them for better maintainability and type safety.
Handle Errors Subscribe to navigation errors and provide user-friendly error messages.
Next Steps
Defining Routes Learn how to define routes with paths, parameters, and nested routes
Route Guards Protect routes with guards to control access and navigation
Lazy Loading Implement lazy loading to optimize your application’s performance