ReviseAlgo Logo

Routing

Guards

Master Angular Route Guards, covering canActivate, canDeactivate, canMatch, functional guards, and authentication protection patterns.

Last Updated: July 15, 2026 12 min read

1. Learning Objectives

In this lesson, you will master Angular route guards. By the end of this topic, you will be able to:

  • Explain the purpose and lifecycle of route guards.
  • Implement canActivate guards to protect routes from unauthorized access.
  • Implement canDeactivate guards to prevent navigation away from unsaved forms.
  • Use canMatch to conditionally match routes based on runtime conditions.
  • Write modern functional guards using the CanActivateFn pattern.

2. Overview

Route guards are functions or classes that the Angular Router calls before or during navigation. They act as checkpoints that decide whether a user is allowed to enter a route, leave a route, or load a route's children. Guards return a boolean, a UrlTree (for redirects), or an Observable/Promise resolving to either.

3. Why This Topic Matters

Route guards are critical for application security and user experience:

  • Access Control: Without guards, any user could type a protected URL (like /admin/dashboard) directly into the browser and access the page, even if they are not authenticated. Guards intercept navigation and redirect unauthorized users to a login page.
  • Preventing Data Loss: If a user is editing a long form and accidentally clicks a navigation link, they lose all their work. A canDeactivate guard prompts them with a confirmation dialog before leaving the page.

4. Real-World Analogy

Think of route guards like **security checkpoints at a building entrance**:

  • canActivate (Entry Security Guard): A guard standing at the door who checks your ID badge before letting you enter a restricted floor. If you don't have the right clearance, you are redirected to the lobby (login page).
  • canDeactivate (Exit Security Guard): A guard who stops you before you leave a secure room, asking "Are you sure you want to leave? You have documents on the desk that haven't been filed yet." This prevents accidental data loss.
  • canMatch (Receptionist Routing): A receptionist who checks your role before deciding which elevator bank to send you to. Admins go to the executive elevator, regular employees go to the standard one.

5. Core Concepts

Angular provides several guard types for different navigation phases:

Guard Type When It Runs Return Values
canActivate Before a route is activated (entered). boolean | UrlTree | Observable | Promise
canDeactivate Before a route is deactivated (left). boolean | UrlTree | Observable | Promise
canMatch Before the router even matches the route definition. boolean | UrlTree | Observable | Promise
canActivateChild Before any child route of a parent is activated. boolean | UrlTree | Observable | Promise

6. Syntax & API Reference

Modern Angular uses functional guards (plain functions) instead of class-based guards. Below is a functional canActivate guard:

Applying Guards to Routes

7. Visual Diagram

This diagram displays the guard evaluation flow during navigation:

8. Live Example — Full Working Code

Below is a functional canDeactivate guard that prevents navigation away from unsaved form changes:

9. Interactive Playground

Try It Yourself Challenges:

  1. Create a role-based guard that only allows users with the "admin" role to access certain routes.
  2. Test what happens when the canDeactivate guard returns false.

10. Common Mistakes

Mistake Why it happens Wrong Correct
Guard returns void instead of boolean Forgetting to return a value from the guard function. TypeScript allows implicit void returns, but the Router interprets undefined as a falsy value, blocking all navigation. if (isAuth) { /* no return */ } return isAuth ? true : router.createUrlTree(['/login'])
Client-side only security Relying solely on Angular guards for security. Guards only prevent client-side navigation; they do not protect API endpoints. A user can bypass guards by calling the API directly. Guard only on frontend Guard on frontend + server-side auth middleware

11. Best Practices

  • Use functional guards: Prefer the modern functional guard pattern (CanActivateFn) over class-based guards. They are simpler, require less boilerplate, and work well with the inject() function.
  • Return UrlTree for redirects: Instead of manually calling router.navigate() and returning false, return a UrlTree from the guard. This lets Angular handle the redirect atomically and avoids race conditions.
  • Always implement server-side authorization: Route guards are a UI convenience, not a security measure. Always validate access on the server side in your API endpoints.
  • Compose multiple guards: You can apply multiple guards to a single route. All guards must return true for navigation to proceed. Use this to separate concerns (e.g. one guard for authentication, another for role-based access).

12. Browser Compatibility/Requirements

Route guards are implemented in TypeScript and execute within the Angular framework's navigation lifecycle. They have no browser-specific requirements and work consistently across all modern browsers.

13. Interview Questions

Q1: What is the difference between canActivate and canMatch?

Answer: canActivate runs after the router has already matched the route and determines whether to activate (render) it. canMatch runs earlier, during the route matching phase, and determines whether the route should even be considered as a match. If canMatch returns false, the router skips the route entirely and tries the next one in the array.

Q2: Why should guards return a UrlTree instead of calling router.navigate()?

Answer: Returning a UrlTree lets Angular handle the redirect atomically as part of the navigation cycle. Calling router.navigate() manually creates a separate, concurrent navigation that can cause race conditions. The UrlTree approach is the recommended pattern for redirect guards.

14. Debugging Exercise

The guard blocks all navigation even for authenticated users. Identify the bug:

View Solution

Diagnosis: Inside the if block that checks authentication, the guard logs a message but does not return true. The function falls through to the redirect statement, redirecting all users (including authenticated ones) to the login page.

Fixed guard:

15. Practice Exercises

Exercise 1: Build a role-based access system

Create an AuthService with a getUserRole() method that returns a role string ("admin", "editor", or "viewer"). Write a guard factory function that accepts allowed roles as parameters and blocks users whose role is not in the list.

16. Scenario-Based Challenge

The Multi-Guard Checkout Flow Challenge:

An e-commerce checkout page requires two guards: one to verify the user is authenticated, and another to verify the shopping cart is not empty. Write both functional guards and apply them to the checkout route. If the user is not authenticated, redirect to login. If the cart is empty, redirect to the products page.

17. Quick Quiz

Q1: What should a canActivate guard return to redirect the user to a different route?

A) false

B) A UrlTree created by router.createUrlTree()

C) A string path like '/login'

Answer: B — Guards should return a UrlTree for redirects, allowing Angular to handle the navigation atomically.

18. Summary & Key Takeaways

  • Route guards intercept navigation to protect routes and prevent data loss.
  • Use canActivate to protect routes from unauthorized access and canDeactivate to prevent leaving unsaved work.
  • Prefer functional guards (CanActivateFn) over class-based guards for simplicity.
  • Return UrlTree for redirects instead of calling router.navigate() manually.
  • Always pair client-side guards with server-side authorization checks.

19. Cheat Sheet

Guard Type Purpose
canActivate Checks before a route is entered (authentication, authorization).
canDeactivate Checks before leaving a route (unsaved changes confirmation).
canMatch Controls whether a route definition is matched at all.
---