← Back to Articles         
What is CanActivate in Angular?

What is CanActivate in Angular?

Published on 30 Sep 2026     7 min read Angular
Route Guards

What is CanActivate in Angular?

What is CanActivate?

CanActivate is an Angular Router route guard used to determine whether a user is allowed to enter/activate a route.

In modern Angular, this is commonly implemented using the functional guard type:

CanActivateFn

For example, before opening:

/dashboard

Angular can check:

User requests /dashboard
        ↓
CanActivate guard
        ↓
Is user authenticated?
       / \
     Yes  No
      ↓    ↓
Dashboard Login

A common use case is protecting routes that require login.


Full Simple Sample Program

We'll protect /dashboard.

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>
      You are successfully logged in.
    </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)
  ]
};

How Does CanActivate Work?

The important route configuration is:

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

The canActivate array tells Angular:

Before activating the Dashboard route, execute authGuard.

The flow is:

User navigates to /dashboard
           ↓
Angular finds dashboard route
           ↓
canActivate: [authGuard]
           ↓
authGuard executes
           ↓
Is user logged in?
       /          \
     Yes           No
      ↓             ↓
 return true    redirect /login
      ↓
Dashboard

Understanding CanActivateFn

The guard is declared:

export const authGuard: CanActivateFn =
  (route, state) => {
    // guard logic
  };

CanActivateFn is the type for a functional canActivate guard.

It receives useful information:

(route, state)

route

Contains information about the route being activated.

For example, you can access:

route.params
route.queryParams
route.data

state

Contains information about the router state, including the requested URL.

For example:

state.url

If the user requests:

/products/10

then state.url could be:

/products/10

This is useful when you want to redirect the user back to the original page after login.


What Can CanActivate Return?

A guard can return several types of results.

1. true

return true;

Means:

Allow navigation.

CanActivate
    ↓
  true
    ↓
Route activated

2. false

return false;

Means:

Cancel the navigation.

CanActivate
    ↓
 false
    ↓
Navigation cancelled

3. Redirect

A guard can return a redirect such as a UrlTree:

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

Means:

/dashboard
    ↓
Guard
    ↓
Not logged in
    ↓
/login

Returning a redirect is generally cleaner than manually calling navigate() and then returning false.


4. Promise

A guard can perform asynchronous logic:

return Promise.resolve(true);

5. Observable

A guard can also return an Observable:

return authService.isAuthenticated$;

This is useful when authentication/authorization state is asynchronous.


CanActivate for Authorization

CanActivate isn't limited to checking whether a user is logged in.

It can also check roles or permissions.

For example:

export const adminGuard: CanActivateFn = () => {

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

  if (authService.getRole() === 'Admin') {
    return true;
  }

  return router.createUrlTree(['/access-denied']);
};

Route:

{
  path: 'admin',
  component: Admin,
  canActivate: [adminGuard]
}

Flow:

/admin
   ↓
CanActivate
   ↓
Is Admin?
  /    \
Yes     No
 ↓       ↓
Admin   Access Denied

Multiple CanActivate Guards

A route can have multiple guards:

{
  path: 'admin',
  component: Admin,
  canActivate: [
    authGuard,
    adminGuard
  ]
}

For example:

/admin
   ↓
authGuard
   ↓
Is authenticated?
   ↓
adminGuard
   ↓
Has Admin access?
   ↓
Admin Component

This allows you to separate responsibilities.

For example:

authGuard
    ↓
Authentication


adminGuard
    ↓
Authorization

CanActivate with Lazy Loading

CanActivate can also protect a lazy-loaded component.

{
  path: 'admin',
  canActivate: [authGuard],

  loadComponent: () =>
    import('./admin')
      .then(m => m.Admin)
}

Here:

/admin
   ↓
canActivate
   ↓
Allowed?
   ↓
Admin route activated

For controlling whether a route configuration should match in the first place, Angular also provides CanMatch.


Older Angular: Class-Based CanActivate

Before functional guards became the preferred style, Angular applications commonly used a class implementing the CanActivate interface.

import { Injectable } from '@angular/core';
import {
  CanActivate,
  Router
} from '@angular/router';

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

@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;
  }
}

Route:

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

Modern Angular commonly uses:

export const authGuard: CanActivateFn = () => {
  // ...
};

So remember:

Older Angular
     ↓
class AuthGuard implements CanActivate


Modern Angular
     ↓
CanActivateFn
     ↓
Functional Guard

CanActivate vs CanActivateChild

Don't confuse these.

CanActivate

Protects a specific route:

{
  path: 'admin',
  component: Admin,
  canActivate: [authGuard]
}

CanActivateChild

Protects child routes:

{
  path: 'admin',
  component: Admin,
  canActivateChild: [authGuard],

  children: [
    {
      path: 'users',
      component: Users
    },
    {
      path: 'reports',
      component: Reports
    }
  ]
}

Think:

CanActivate
     ↓
Can I enter this route?


CanActivateChild
     ↓
Can I enter its child routes?

Advantages

  • Prevents unauthorized navigation in the Angular UI.
  • Useful for authentication checks.
  • Useful for role/permission checks.
  • Can redirect unauthenticated users to Login.
  • Supports synchronous and asynchronous checks.
  • Can be reused across multiple routes.
  • Functional guards work naturally with Angular's inject() API.

Important Security Point

CanActivate is client-side route protection, not server-side security.

Even if Angular protects:

/admin

a user could attempt to directly call:

GET /api/admin/users

Therefore, your ASP.NET Core API must still enforce authorization:

[Authorize(Roles = "Admin")]
[HttpGet]
public IActionResult GetUsers()
{
    // ...
}

Think:

Angular CanActivate
        ↓
Controls UI navigation


ASP.NET Core [Authorize]
        ↓
Protects API/resources

You generally need both.


Key Points

  • CanActivate determines whether a route can be activated.
  • In modern Angular, use:
CanActivateFn
  • Configure it using:
canActivate: [authGuard]
  • true → allow navigation.
  • false → cancel navigation.
  • A UrlTree/redirect result → redirect to another route.
  • Guards can also return asynchronous results using Promise or Observable.
  • Common uses are authentication and authorization.
  • Modern Angular favors functional guards over older class-based guards.
  • CanActivate does not replace backend authorization.

Interview Questions and Answers

1. What is CanActivate?

CanActivate is an Angular route guard used to determine whether a route can be activated.


2. How do you use CanActivate in modern Angular?

Create a functional guard:

export const authGuard: CanActivateFn = () => {

  const authService = inject(AuthService);

  return authService.isLoggedIn();
};

Then attach it:

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

3. What happens when CanActivate returns true?

Angular allows the navigation and activates the route.


4. What happens when it returns false?

Angular cancels the navigation.


5. How do you redirect from a CanActivate guard?

Return a redirect such as a UrlTree:

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

6. Can CanActivate perform asynchronous checks?

Yes. Guards can return asynchronous results using a Promise or Observable, which is useful when authentication state must be resolved asynchronously.


7. Can we have multiple CanActivate guards?

Yes:

canActivate: [
  authGuard,
  adminGuard
]

This is useful for separating authentication and authorization checks.


8. CanActivate vs CanActivateChild?

CanActivate protects a particular route, while CanActivateChild controls access to child routes.


Interview-ready answer

CanActivate is an Angular route guard that determines whether a route can be activated. In modern Angular, it is commonly implemented using CanActivateFn. The guard can return true to allow navigation, false to cancel it, or a redirect result such as a UrlTree to send the user to another route. It is commonly used for authentication and authorization checks.

← Back to Articles