Skip to main content
Angular FundamentalsยทLesson 4 of 5

Routing & Navigation

The Angular Router maps URL paths to components. When the URL changes, the router swaps out the active component without a full page reload.

Basic Setup

When you ran ng new with routing enabled, Angular generated app-routing.module.ts:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent }    from './home/home.component';
import { AboutComponent }   from './about/about.component';
import { NotFoundComponent } from './not-found/not-found.component';

const routes: Routes = [
  { path: '',       component: HomeComponent },
  { path: 'about',  component: AboutComponent },
  { path: '**',     component: NotFoundComponent },  // catch-all
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

In app.component.html, add <router-outlet> where views should render:

<app-navbar></app-navbar>
<router-outlet></router-outlet>

Use routerLink instead of href to navigate without a page reload:

<nav>
  <a routerLink="/"      routerLinkActive="active" [routerLinkActiveOptions="{exact: true}">Home</a>
  <a routerLink="/about" routerLinkActive="active">About</a>
</nav>

routerLinkActive adds the CSS class when the route is active.

Route Parameters

Pass dynamic segments in the URL:

const routes: Routes = [
  { path: 'users/:id', component: UserDetailComponent },
];

Read the parameter in the component:

import { ActivatedRoute } from '@angular/router';

export class UserDetailComponent implements OnInit {
  userId!: string

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.userId = this.route.snapshot.paramMap.get('id')!
    // Or subscribe for changes: this.route.paramMap.subscribe(...)
  }
}

Programmatic Navigation

Navigate from code using the Router service:

import { Router } from '@angular/router';

export class LoginComponent {
  constructor(private router: Router) {}

  onLogin() {
    // after auth succeeds:
    this.router.navigate(['/dashboard'])
    // with params:
    this.router.navigate(['/users', userId])
  }
}

Route Guards

Protect routes from unauthorised access with guards:

ng generate guard auth
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(private auth: AuthService, private router: Router) {}

  canActivate(): boolean {
    if (this.auth.isLoggedIn()) return true
    this.router.navigate(['/login'])
    return false
  }
}

Apply to a route:

{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }

What a Routed Nav Looks Like

Ctrl+Enter
HTML
CSS
JS
Preview

Lazy Loading

For large apps, load feature modules on demand to reduce initial bundle size:

const routes: Routes = [
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
  }
];

The admin bundle is only downloaded when a user visits /admin.