Route Guards
Protect routes from unauthorized access using the modern, function-based CanActivate guard.
What Route Guards Do
A route guard runs before a navigation completes, and can allow it, redirect elsewhere, or cancel it — the standard Angular mechanism for authentication and authorization checks tied to specific routes.
A Functional CanActivate Guard
Modern Angular defines guards as plain functions rather than injectable classes, using inject() to access any services they need.
// auth.guard.tsimport { inject } from '@angular/core';import { Router, CanActivateFn } from '@angular/router';import { AuthService } from './auth.service';
export const authGuard: CanActivateFn = () => { const authService = inject(AuthService); const router = inject(Router);
if (authService.isLoggedIn()) { return true; }
return router.parseUrl('/login'); // redirect};Applying a Guard to a Route
export const routes: Routes = [ { path: 'dashboard', component: DashboardComponent, canActivate: [authGuard] },];A route guard runs entirely in the browser and can be bypassed by a determined user inspecting the app's JavaScript — always enforce real authorization on your backend API as well, treating the guard as a navigation convenience, not a security boundary on its own.
Other Guard Types
| Guard | Purpose |
|---|---|
| CanActivate | Controls whether a route can be entered at all |
| CanActivateChild | Applies the same check to all child routes of a parent |
| CanDeactivate | Controls whether a user can navigate away (e.g. an unsaved-changes prompt) |
| CanMatch | Controls whether a route is even considered a match, useful with lazy loading |
| Resolve | Pre-fetches data before a route activates, so the component never renders without it |
Common Beginner Mistakes
Guards run entirely on the client — treat them as a UX-level redirect, and always enforce real authorization on your actual backend/API.
Modern Angular recommends the simpler functional guard syntax (CanActivateFn) shown here for new code — the class-based form still works but requires more boilerplate.
FAQs
Yes — canActivate accepts an array, and every guard in it must return true (or not redirect) for the navigation to proceed.
Returning false simply cancels the navigation with no redirect; returning a UrlTree cancels it and redirects to that URL in one step.
Summary
Functional guards give you a concise, testable way to gate navigation based on authentication or other conditions. Next, you'll learn lazy loading, for splitting your app's code by route.