Route Guards: Protecting Navigation
10 min read
Why Route Guards?
Route guards let you run logic before Angular activates or deactivates a route. The most common use case is authentication: redirect unauthenticated users to the login page before they can see protected content.
Functional Guards (Angular 15+)
Modern Angular favours functional guards — plain functions (or arrow functions) rather than classes implementing CanActivate. A guard returns true to allow navigation, false to block it, or a UrlTree to redirect.
ts
// auth.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from '../services/auth.service';
export const authGuard: CanActivateFn = (route, state) => {
const auth = inject(AuthService);
const router = inject(Router);
if (auth.isLoggedIn()) {
return true;
}
// Preserve the intended URL so we can redirect after login
return router.createUrlTree(['/login'], {
queryParams: { returnUrl: state.url }
});
};ts
// app.routes.ts
import { Routes } from '@angular/router';
import { authGuard } from './guards/auth.guard';
export const routes: Routes = [
{ path: '', loadComponent: () => import('./home/home.component').then(m => m.HomeComponent) },
{ path: 'login', loadComponent: () => import('./login/login.component').then(m => m.LoginComponent) },
{
path: 'dashboard',
canActivate: [authGuard],
loadComponent: () => import('./dashboard/dashboard.component').then(m => m.DashboardComponent)
},
{
path: 'admin',
canActivate: [authGuard, adminGuard], // multiple guards — all must pass
loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES)
}
];Other Guard Types
canActivate— runs before activating the routecanActivateChild— runs before activating any child routecanDeactivate— runs before leaving a route (e.g. unsaved form warning)canMatch— runs before the router even tries to match the route (replacescanLoad)resolve— pre-fetches data before the component is created
canDeactivate receives the component instance as its first argument, so the guard can call a method like component.hasUnsavedChanges() to decide whether to warn the user before navigation.
Ready to test yourself?
Practice Angular— quiz & coding exercises