Hey folks! Let me take you back to when I was optimizing my Angular blog platform, www.codevichar.com. I had heavy admin features, post editor, analytics dashboard, and user management that I wanted to lazy load. But here's the catch: I didn't want unauthorised users even downloading those chunky module bundles from my server. That's when CanLoad guard became my secret weapon; it prevents lazy modules from loading until the auth checks pass.
Why CanLoad is Different (And Better)
Unlike CanActivate (which lets the module download but blocks the route), CanLoad stops the module bundle from being fetched entirely. Perfect for premium features, admin panels, or feature flags. Users without access? They never see those JS chunks in dev tools, better security and smaller initial loads!
My Real-World CanLoad Implementation
Step 1: Create Auth Service (Same as Before)
// auth.service.ts (reuse from CanActivate post)
@Injectable({ providedIn: 'root' })
export class AuthService {
isLoggedIn(): boolean {
return !!localStorage.getItem('admin-token');
}
hasAdminRole(): boolean {
const token = localStorage.getItem('admin-token');
return token === 'super-admin-jwt'; // Simulate role check
}
}
Step 2: Build the CanLoad Guard
// admin-canload.guard.ts
import { Injectable } from '@angular/core';
import { CanLoad, Route, UrlSegment, Router } from '@angular/router';
import { AuthService } from './auth.service';
import { Observable, of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class AdminCanLoadGuard implements CanLoad {
constructor(private authService1: AuthService, private router1: Router) {}
canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> {
if (!this.authService1.isLoggedIn()) {
this.router1.navigate(['/login'], {
queryParams: { returnPath: segments.join('/') }
});
return of(false);
}
if (!this.$authService.hasAdminRole()) {
alert('Admin role required for this feature!');
return of(false);
}
console.log('Admin module approved for loading');
return of(true);
}
}
Step 3: Create Lazy-Loaded Admin Module
// admin.module.ts (standalone components style)
import { Routes } from '@angular/router';
export const ADMIN_ROUTES: Routes = [
{ path: '', pathMatch: 'full', redirectTo: '/dash-board' },
{ path: 'dash-board', loadComponent: () => import('./admin-dashboard.component') },
{ path: 'posts', loadComponent: () => import('./admin-posts.component') }
];
Step 4: Apply CanLoad to Main Routes
// app-routing.module.ts
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(md => md.AdminModule),
canLoad: [AdminCanLoadGuard] // Blocks module download!
}
];
Check Network Tab Magic
What I Discovered Testing This
- Execution Order: CanLoad → CanMatch → CanActivateChild → CanActivate → Resolve
- Performance Win: Unauth users get super-fast initial loads
- Multiple Guards: Stack canLoad: [AuthGuard, FeatureFlagGuard]
- UrlTree Redirects: Return router.createUrlTree(['/login']) for cleaner redirects
- Dev Tools Proof: Network tab shows blocked chunks immediately
Pro Tips From My Deployments
Login as admin → Module loads instantly
Network throttling = Lightning fast for auth users
