version: "1.0.1"
Use a functional CanActivateFn guard. Class-based guards are deprecated.
ts
// 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 auth = inject(AuthService);
const router = inject(Router);
return auth.isLoggedIn()
? true
: router.createUrlTree(['/login'], {
queryParams: { returnUrl: state.url },
});
};
Apply it to a lazy-loaded feature route:
ts
// app.routes.ts
import { Routes } from '@angular/router';
import { authGuard } from './auth.guard';
export const routes: Routes = [
{
path: 'dashboard',
canActivate: [authGuard],
loadComponent: () =>
import('./dashboard/dashboard.component')
.then(m => m.DashboardComponent),
title: 'Dashboard',
},
];
Configure the router:
ts
import { ApplicationConfig } from '@angular/core';
import {
provideRouter,
withComponentInputBinding,
} from '@angular/router';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withComponentInputBinding()),
],
};
Keep access-control logic out of the route config—route config should contain route metadata and guard references, while the guard handles authorization. Use a ResolveFn<T> when critical data must be fetched before navigation.