Chapter 8: Routing and Navigation in Angular (Standalone)
Routing in Angular enables navigation between views, making it possible to create single-page applications (SPA). Angular 20, using standalone components, has modernized routing even further with simplified configurations and lazy loading support. In this chapter, we’ll learn how to set up routes, pass parameters, use guards, and implement lazy loading — all using standalone APIs.
Setting Up Routing with Standalone Components
1. Create Standalone Components
ng generate component home --standalone
ng generate component about --standalone
ng generate component contact --standalone
2. Define Routes in main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter, Routes } from '@angular/router';
import { HomeComponent } from './app/home/home.component';
import { AboutComponent } from './app/about/about.component';
import { ContactComponent } from './app/contact/contact.component';
import { AppComponent } from './app/app.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
];
bootstrapApplication(AppComponent, {
providers: [provideRouter(routes)],
});
3. Use <router-outlet> in Root Component
<nav>
<a routerLink="/">Home</a> |
<a routerLink="/about">About</a> |
<a routerLink="/contact">Contact</a>
</nav>
<router-outlet></router-outlet>
Route Parameters
1. Define Dynamic Route
{ path: 'user/:id', component: UserComponent }
2. Access Parameter in Component
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CommonModule } from '@angular/common';
@Component({
standalone: true,
imports: [CommonModule],
selector: 'app-user',
template: '<p>User ID: {{ userId }}</p>'
})
export class UserComponent {
userId = '';
constructor(private route: ActivatedRoute) {
this.userId = this.route.snapshot.paramMap.get('id') || '';
}
}
Query Parameters
Example: /products?category=books
this.route.queryParamMap.subscribe(params => {
const category = params.get('category');
});
Lazy Loading with Standalone Components
1. Create a Standalone Lazy Component
ng generate component dashboard --standalone
2. Setup Lazy Route
{
path: 'dashboard',
loadComponent: () => import('./app/dashboard/dashboard.component').then(m => m.DashboardComponent)
}
No need to create NgModules. This reduces boilerplate and improves performance using Angular’s modern lazy loading technique.
Route Guards (AuthGuard Example)
1. Create the Guard
import { CanActivateFn } from '@angular/router';
export const authGuard: CanActivateFn = (route, state) => {
const isAuthenticated = true; // Replace with real logic
return isAuthenticated;
};
2. Apply the Guard
{
path: 'dashboard',
loadComponent: () => import('./app/dashboard/dashboard.component').then(m => m.DashboardComponent),
canActivate: [authGuard]
}
Best Practices
- Use standalone components for better tree-shaking and easier lazy loading.
- Always keep routes in a central place like
main.ts
for small projects or create a routing config file. - Use guards to secure private routes and check roles/permissions.
- Use query parameters for optional filters or sorting.
Conclusion
Angular’s routing system is now simpler and more powerful than ever with the standalone architecture. From simple routes to dynamic parameters, lazy loading, and route guards — Angular 20 gives you full control to build scalable SPAs without extra module complexity.
Next Steps
In Chapter 9, we’ll explore how to fetch data from APIs using Angular’s HttpClient
, handle Observables, and integrate services with RESTful endpoints in real-world scenarios.