How to Use Angular Router Navigate to Switch Between Routes: A Complete Guide
Call router.navigate() with an array of URL segments to move between routes programmatically, or use router.navigateByUrl() when you have a complete URL string or pre-built UrlTree.
The Angular Router provides a powerful navigation system for single-page applications. Understanding how to use angular router navigate effectively is essential for building dynamic user experiences in any Angular application. This guide examines the actual implementation in the angular/angular repository to show you exactly how programmatic navigation works under the hood.
How Angular Router Navigate Works Under the Hood
When you call router.navigate() in your component or service, the Angular Router executes a precise four-step process defined in packages/router/src/router.ts:
-
Creates a UrlTree – The router first transforms your navigation commands into a lightweight in-memory representation called a
UrlTree. This happens in thecreateUrlTreemethod around line 331 of the router source. -
Applies route-matching rules – The router walks your route configuration tree to find a match. This recognition phase, implemented in the
recognizefunction (line 506), resolves parameters and identifies which components to activate. -
Runs navigation guards – Before completing the transition, the router executes
CanActivate,CanDeactivate, andResolvehooks. TherunCanActivatemethod (line 1016) handles this validation phase, cancelling navigation if any guard rejects the transition. -
Commits the navigation – Finally, the router updates the browser URL via the
LocationStrategyand activates the matched components throughRouterOutlet. This commit phase occurs around line 1243 in the source.
Angular Router Navigate vs NavigateByUrl
The Router service exposes two primary methods for programmatic navigation, each serving different use cases:
router.navigate(commands, extras?) accepts an array of URL segments and resolves them relative to the current ActivatedRoute unless you specify a leading slash. Use this when building URLs dynamically from route segments.
router.navigateByUrl(url, extras?) accepts a string or pre-built UrlTree representing the complete URL. Use this when you already have a fully formed URL or need absolute navigation without segment resolution.
How to Use Angular Router Navigate: Practical Examples
Navigating from a Component with Relative Paths
When navigating from within a component, inject both Router and ActivatedRoute to maintain relative navigation context:
import { Component } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-product-list',
template: `
<button (click)="viewDetails(42)">View Details</button>
`,
})
export class ProductListComponent {
constructor(
private router: Router,
private route: ActivatedRoute
) {}
viewDetails(productId: number): void {
// Navigate relative to the current route
this.router.navigate(['details', productId], {
relativeTo: this.route,
queryParams: { ref: 'list' },
fragment: 'info',
});
}
}
Navigating from a Service with Absolute Paths
For global navigation actions like logout or authentication redirects, use absolute paths via navigateByUrl:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable({ providedIn: 'root' })
export class AuthService {
constructor(private router: Router) {}
logout(): void {
// Clear authentication state
localStorage.removeItem('token');
// Absolute navigation to login page
this.router.navigateByUrl('/login');
}
redirectToDashboard(): void {
// Alternative using navigate with absolute path
this.router.navigate(['/', 'admin', 'dashboard']);
}
}
Working with Named Outlets and UrlTree
For complex layouts with multiple named outlets, construct a UrlTree explicitly:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-layout',
template: `
<button (click)="openSidePanel()">Open Stats</button>
<router-outlet></router-outlet>
<router-outlet name="sidebar"></router-outlet>
`,
})
export class LayoutComponent {
constructor(private router: Router) {}
openSidePanel(): void {
// Create UrlTree for multiple outlets
const tree = this.router.createUrlTree(
['/dashboard', {
outlets: {
primary: ['main'],
sidebar: ['stats']
}
}],
{ queryParams: { period: 'monthly' } }
);
this.router.navigateByUrl(tree);
}
}
Handling Query Parameters and Fragments
Both navigation methods accept a NavigationExtras object for controlling URL composition:
queryParams: Object literal appended as query stringfragment: Hash fragment for page anchorsqueryParamsHandling:'preserve'to keep existing params,'merge'to combinepreserveFragment: Boolean to keep the current hash
Example with parameter preservation:
// Merge new params with existing ones
this.router.navigate(['../sibling'], {
relativeTo: this.route,
queryParams: { sort: 'desc' },
queryParamsHandling: 'merge',
preserveFragment: true,
});
Summary
- Angular router navigate transforms navigation commands into a
UrlTree, matches routes inpackages/router/src/router.ts, runs guards, and commits the navigation by updating the browser URL and activating components. - Use
router.navigate()with an array of segments for relative navigation and dynamic URL construction. - Use
router.navigateByUrl()when you have a complete URL string or pre-builtUrlTree. - Inject
ActivatedRouteto maintain relative navigation context within components. - Leverage
NavigationExtrasto manage query parameters, fragments, and navigation behavior.
Frequently Asked Questions
What is the difference between router.navigate and router.navigateByUrl?
router.navigate accepts an array of URL segments that the router resolves relative to the current ActivatedRoute, making it ideal for building URLs dynamically from route parameters. router.navigateByUrl accepts a complete URL string or UrlTree object, performing absolute navigation without segment resolution. According to the Angular source code in packages/router/src/router.ts, both methods eventually create a UrlTree, but navigate processes commands through createUrlTree while navigateByUrl parses the string directly or uses the provided tree.
How do I preserve query parameters when using angular router navigate?
Pass queryParamsHandling: 'preserve' in the NavigationExtras object to keep existing query parameters, or use 'merge' to combine current parameters with new ones. For example: this.router.navigate(['new-path'], { queryParamsHandling: 'preserve' }). You can also use preserveFragment: true to maintain the URL hash. This behavior is handled during the URL tree creation phase in the router's navigation pipeline.
Can I navigate to multiple named outlets in a single call?
Yes, construct a UrlTree using router.createUrlTree with an outlets object mapping outlet names to path segments, then pass that tree to router.navigateByUrl. For example: createUrlTree(['/dashboard', { outlets: { primary: ['main'], sidebar: ['stats'] } }]). This creates a complex URL like /dashboard/(main//sidebar:stats) that activates multiple components simultaneously in different RouterOutlet locations.
Why is my router.navigate call not working?
Common causes include missing RouterModule imports in your feature module, attempting navigation before the router has finished initializing, or relative navigation without providing the ActivatedRoute reference. Guards like CanActivate or CanDeactivate may also be blocking the navigation. Check the browser console for navigation cancellation errors and verify that your route configuration in RouterModule.forRoot() or forChild() actually defines the target path. The navigation lifecycle in packages/router/src/router.ts shows that any guard rejection will cancel the transition before the URL updates.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →