If you want Angular route preloading but only for routes allowed by a user's role (instead of preloading everything eagerly). This is a common optimization when you use PreloadAllModules, but don't want to waste bandwidth on routes a user will never access.
You can extend Angular's PreloadingStrategy using CustomPreLoadingStrategy class to decide which routes should preload. Inject this CustomPreLoadingStrategy inside app.config.ts using withPreloading.
custom-preloading.ts
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { EMPTY, Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class CustomPreLoadingStrategy implements PreloadingStrategy {
private userRole = 'user';
preload(route: Route, fn: () => Observable<any>): Observable<any> {
if (
route.data?.['preload'] &&
route.data?.['roles']?.includes(this.userRole)
) {
console.log(`Preloading route /${route.path} for role: ${this.userRole}`);
return fn();
}
console.log(`Skipping preload for route: /${route.path}`);
return EMPTY;
}
}
app.config.ts
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter, withPreloading } from '@angular/router';
import { routes } from './app.routes';
import {
provideClientHydration,
withEventReplay,
} from '@angular/platform-browser';
import { CustomPreLoadingStrategy } from './custom-preloading';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes, withPreloading(CustomPreLoadingStrategy)),
provideClientHydration(withEventReplay()),
],
};
When defining lazy-loaded routes, specify which roles can preload them:
app.routes.ts
import { Routes } from '@angular/router';
export const routes: Routes = [
{
path: 'home',
loadComponent: () =>
import('./components/home/home.component').then((m) => m.HomeComponent),
},
{
path: 'dashboard',
loadComponent: () =>
import('./components/dashboard/dashboard.component').then(
(m) => m.DashboardComponent
),
data: { preload: true, roles: ['admin', 'user'] },
},
{
path: 'admin',
loadComponent: () =>
import('./components/admin/admin.component').then(
(m) => m.AdminComponent
),
data: { preload: true, roles: ['admin'] },
},
{
path: 'settings',
loadComponent: () =>
import('./components/settings/settings.component').then(
(m) => m.SettingsComponent
),
data: { preload: false },
},
{
path: '**',
redirectTo: 'home',
pathMatch: 'full',
},
];
✅ Result: If a logged-in user is admin, the admin and dashboard routes preload. If the user is just user, only dashboard and home preload. Unauthorized routes won't preload, saving bandwidth.