← Back to Articles         
What is a Route Guard in Angular?

What is a Route Guard in Angular?

Published on 30 Sep 2026     7 min read Angular
Route Guards

What is a Route Guard in Angular?

What is a Route Guard?

A route guard in Angular controls whether navigation to or from a route should be allowed, blocked, or redirected.

A common example is protecting an Admin page.

User tries /admin
       ↓
Route Guard executes
       ↓
Is user logged in?
       ↓
   Yes ─────→ Allow /admin

   No ──────→ Redirect /login

Route guards are commonly used for:

  • Authentication
  • Authorization / role checks
  • Preventing access to protected pages
  • Preventing users from leaving a page with unsaved changes
  • Controlling whether certain routes should be matched or loaded

In modern standalone Angular, functional guards are the preferred style.


Full Simple Sample Program

Let's protect a /dashboard route.

If the user is logged in:

/dashboard → Allowed

If not:

/dashboard → Redirect to /login

auth.service.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private loggedIn = false;

  login(): void {
    this.loggedIn = true;
  }

  logout(): void {
    this.loggedIn = false;
  }

  isLoggedIn(): boolean {
    return this.loggedIn;
  }
}

auth.guard.ts

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';

import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = (route, state) => {

  const authService = inject(AuthService);
  const router = inject(Router);

  if (authService.isLoggedIn()) {
    return true;
  }

  return router.createUrlTree(['/login']);
};

login.ts

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

import { AuthService } from './auth.service';

@Component({
  selector: 'app-login',
  standalone: true,
  template: `
    <h2>Login</h2>

    <button (click)="login()">
      Login
    </button>
  `
})
export class Login {

  constructor(
    private authService: AuthService,
    private router: Router
  ) {
  }

  login(): void {

    this.authService.login();

    this.router.navigate(['/dashboard']);
  }
}

dashboard.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-dashboard',
  standalone: true,
  template: `
    <h2>Dashboard</h2>

    <p>Welcome to the protected Dashboard.</p>
  `
})
export class Dashboard {
}

app.routes.ts

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

import { Login } from './login';
import { Dashboard } from './dashboard';
import { authGuard } from './auth.guard';

export const routes: Routes = [
  {
    path: 'login',
    component: Login
  },
  {
    path: 'dashboard',
    component: Dashboard,
    canActivate: [authGuard]
  }
];

app.ts

import { Component } from '@angular/core';
import { RouterLink, RouterOutlet } from '@angular/router';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    RouterLink,
    RouterOutlet
  ],
  template: `
    <h1>My Application</h1>

    <nav>
      <a routerLink="/login">Login</a> |
      <a routerLink="/dashboard">Dashboard</a>
    </nav>

    <hr>

    <router-outlet></router-outlet>
  `
})
export class App {
}

app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes)
  ]
};

Explanation

The important route is:

{
  path: 'dashboard',
  component: Dashboard,
  canActivate: [authGuard]
}

This tells Angular:

Before activating Dashboard, execute authGuard.

The guard is:

export const authGuard: CanActivateFn = (route, state) => {

  const authService = inject(AuthService);
  const router = inject(Router);

  if (authService.isLoggedIn()) {
    return true;
  }

  return router.createUrlTree(['/login']);
};

When User Is Logged In

The guard checks:

authService.isLoggedIn()

If it returns:

true

the guard returns:

return true;

Therefore:

User requests /dashboard
        ↓
authGuard
        ↓
isLoggedIn() = true
        ↓
Guard returns true
        ↓
Navigation allowed
        ↓
Dashboard displayed

When User Is Not Logged In

If:

authService.isLoggedIn()

returns false, we return:

return router.createUrlTree(['/login']);

This tells Angular Router to redirect the navigation to /login.

User requests /dashboard
        ↓
authGuard
        ↓
isLoggedIn() = false
        ↓
Return /login UrlTree
        ↓
Dashboard not activated
        ↓
Login displayed

What Can a Route Guard Return?

A guard can return values such as:

true

Allow navigation.

false

Block navigation.

Or a redirect:

router.createUrlTree(['/login'])

Angular guards can also work asynchronously using:

Promise
Observable

This is useful when authorization logic depends on asynchronous data.


Important Route Guard Types

Modern Angular Router provides several guard functions.

Guard Purpose
CanActivateFn Can the user enter this route?
CanActivateChildFn Can the user enter child routes?
CanDeactivateFn Can the user leave this route?
CanMatchFn Should this route configuration match?

1. CanActivate

Used to control whether a route can be activated.

Example:

{
  path: 'dashboard',
  component: Dashboard,
  canActivate: [authGuard]
}

Typical use:

Is user authenticated?
Is user authorized?
Does user have required role?

2. CanActivateChild

Protects child routes.

Suppose:

/admin
/admin/users
/admin/reports
/admin/settings

Instead of placing the same guard on every child, you can protect child navigation:

{
  path: 'admin',
  component: Admin,
  canActivateChild: [adminGuard],
  children: [
    {
      path: 'users',
      component: Users
    },
    {
      path: 'reports',
      component: Reports
    }
  ]
}

Conceptually:

/admin
   │
   └── adminGuard
          │
          ├── /users
          └── /reports

3. CanDeactivate

Controls whether the user can leave a route.

For example, the user is editing:

/products/edit/10

and has unsaved changes.

Then the user clicks Home.

Unsaved changes?
       ↓
      Yes
       ↓
"Are you sure you want to leave?"

A CanDeactivate guard is useful for:

  • Unsaved forms
  • Unsaved edits
  • Multi-step forms

4. CanMatch

CanMatch determines whether a route should be considered a match.

For example:

{
  path: 'admin',
  canMatch: [adminGuard],
  loadComponent: () =>
    import('./admin')
      .then(m => m.Admin)
}

It can be useful when route matching depends on conditions such as permissions or feature access.


Old Angular: Class-Based Guards

In older Angular applications, guards were commonly implemented as classes.

For example:

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(
    private authService: AuthService,
    private router: Router
  ) {
  }

  canActivate(): boolean {

    if (this.authService.isLoggedIn()) {
      return true;
    }

    this.router.navigate(['/login']);

    return false;
  }
}

Then:

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

Modern Angular favors functional guards:

export const authGuard: CanActivateFn = () => {

  const authService = inject(AuthService);

  return authService.isLoggedIn();
};

So remember:

Older Angular
     ↓
Class-based guard


Modern Angular
     ↓
Functional guard

Route Guard Is NOT API Security

This is extremely important.

Suppose Angular has:

canActivate: [authGuard]

This protects navigation in the Angular UI, but it does not securely protect your ASP.NET Core Web API.

A knowledgeable user could bypass the Angular application and directly call:

GET /api/admin/users

Therefore:

Angular Route Guard
        ↓
Controls client-side navigation


ASP.NET Core Authorization
        ↓
Protects server-side API/resources

For an Angular + ASP.NET Core application, you normally need both:

Browser
   ↓
Angular
   ↓
Route Guard
   ↓
Component
   ↓
HTTP request
   ↓
ASP.NET Core Web API
   ↓
Authentication + Authorization

For example, your Web API might independently require:

[Authorize(Roles = "Admin")]

The Angular guard improves navigation and user experience; the backend remains the authoritative security boundary.


Key Points

  • Route guards control Angular Router navigation.
  • CanActivateFn determines whether a route can be activated.
  • A guard can allow navigation:
return true;
  • It can block navigation:
return false;
  • It can redirect:
return router.createUrlTree(['/login']);
  • Modern Angular commonly uses functional guards.
  • Common guards include:
CanActivate
CanActivateChild
CanDeactivate
CanMatch
  • Route guards are commonly used for authentication and authorization-related navigation.
  • A route guard does not replace backend security.

Interview Questions and Answers

1. What is a route guard in Angular?

A route guard controls whether Angular Router should allow, block, or redirect navigation based on application logic such as authentication or authorization.


2. How do you protect a route?

Use canActivate:

{
  path: 'dashboard',
  component: Dashboard,
  canActivate: [authGuard]
}

3. What does returning true from a guard mean?

return true;

It means Angular can continue the navigation.


4. What does returning false mean?

return false;

It cancels the current navigation.


5. How do you redirect an unauthorized user?

A common approach is to return a UrlTree:

return router.createUrlTree(['/login']);

6. What is CanDeactivate used for?

CanDeactivate controls whether the user can leave a route. It is commonly used to warn users about unsaved form changes.


7. What is CanMatch?

CanMatch determines whether Angular Router should consider a particular route configuration as a match.


8. Class-based guard vs functional guard?

Older Angular code commonly used class-based guards:

class AuthGuard implements CanActivate

Modern Angular commonly uses functional guards:

const authGuard: CanActivateFn = ...

9. Does a route guard secure a Web API?

No. A route guard only controls client-side Angular navigation. The Web API must perform its own authentication and authorization.

For example, in ASP.NET Core:

[Authorize]

or:

[Authorize(Roles = "Admin")]

should protect sensitive API endpoints.


Interview-ready answer

A route guard in Angular controls navigation based on conditions such as authentication, authorization, or unsaved changes. For example, CanActivate can prevent an unauthenticated user from opening /dashboard and redirect them to /login. Modern Angular commonly uses functional guards such as CanActivateFn, CanDeactivateFn, and CanMatchFn. Route guards protect client-side navigation and do not replace server-side API authorization.

← Back to Articles