All topics
Routingintermediate

Functional Route Guards

Explain CanActivate and related guards as functions, and how they control whether navigation is allowed to proceed.

Route guards let you intercept navigation before it completes, deciding whether it should be allowed, redirected, or blocked entirely — the classic use case is preventing an unauthenticated user from reaching a protected route. Since Angular 14.2, guards can be written as plain functions (CanActivateFn, CanDeactivateFn, etc.) rather than injectable classes implementing an interface, and since Angular 15+ this functional style is the recommended default, mirroring the same shift functional interceptors made.

A route guard is like a bouncer checking IDs at a club entrance — you don't get in without the right credentials, but if you don't qualify, the bouncer can point you toward a different, appropriate entrance (a redirect) instead of just leaving you standing on the sidewalk.

Key Concepts

1
A CanActivateFn receives the target route snapshot and router state, runs within an injection context (so it can call inject() to grab any service it needs, like an AuthService), and returns (synchronously, or as a Promise/Observable) either true to allow navigation, false to block it, or a UrlTree (typically from router.createUrlTree() or router.parseUrl()) to redirect somewhere else instead.
CanActivateFninject()AuthServicePromiseObservable
2
Multiple guards can be attached to the same route via the canActivate array, and all of them must resolve truthy for navigation to proceed — if any guard returns false or a UrlTree, the others are effectively short-circuited from actually completing the navigation, though the exact evaluation order and cancellation semantics are a common deep-dive interview question.
canActivatefalseUrlTree
3
A sharp answer distinguishes CanActivate (guarding entry into a route) from CanActivateChild (guarding entry into any child route without repeating the guard on every child) and CanMatch (deciding whether a route even matches at all during route matching, which is powerful for showing entirely different routes/components based on conditions like feature flags, not just blocking access to a fixed route).
CanActivateCanActivateChildCanMatch