π Dynamic Management β
Add, remove, and reassign outposts at runtime without restarting the application.
β‘ Static vs Dynamic β
Static setup β all outposts defined at initialization:
const citadel = createNavigationCitadel(router, {
outposts: [
{ name: 'auth', handler: authHandler },
{ name: 'analytics', handler: analyticsHandler, hooks: [NavigationHooks.AFTER_EACH] },
],
});Dynamic management β outposts added, removed, or reassigned at runtime:
// Later, when admin module loads
citadel.deployOutpost({
scope: NavigationOutpostScopes.ROUTE,
name: 'admin-only',
handler: adminHandler,
});
// When feature is disabled
citadel.abandonOutpost(NavigationOutpostScopes.ROUTE, 'admin-only');Both approaches can be combined β start with core outposts, add module-specific ones dynamically.
π¦ Deploy & Abandon β
Adding Outposts β
// Module loaded lazily β registers its guards
export function registerBillingModule(citadel: NavigationCitadelAPI) {
citadel.deployOutpost([
{
scope: NavigationOutpostScopes.ROUTE,
name: 'billing:premium',
handler: premiumHandler,
},
{
scope: NavigationOutpostScopes.ROUTE,
name: 'billing:trial-expired',
handler: trialHandler,
},
]);
}Removing Outposts β
// Feature flag disabled β remove the guard
citadel.abandonOutpost(NavigationOutpostScopes.GLOBAL, 'feature-flags');
// Module unloaded
citadel.abandonOutpost(NavigationOutpostScopes.ROUTE, ['billing:premium', 'billing:trial-expired']);abandonOutpost returns true if the outpost was found and removed, false otherwise.
πΊοΈ Assign & Revoke Routes β
Outpost-to-route binding can also be managed dynamically, without changing route definitions.
Static assignment (in route config):
const routes = [
{
path: '/admin',
name: 'admin',
meta: { outposts: ['admin-only'] },
},
];Dynamic assignment (at runtime):
// Add outpost requirement to a route
citadel.assignOutpostToRoute('admin', 'audit-log');
// Route now requires both: ['admin-only', 'audit-log']Dynamic revocation:
// Remove outpost requirement from a route
citadel.revokeOutpostFromRoute('admin', 'audit-log');
// Route now requires only: ['admin-only']Duplicates are automatically filtered β calling assignOutpostToRoute multiple times with the same name is safe.
π‘ Use Cases β
| Scenario | Deploy / Abandon | Assign / Revoke |
|---|---|---|
| Lazy feature modules | Module registers outposts on load | Module assigns outposts to its routes |
| Role-based access | Deploy role-specific outposts after login | β |
| Multi-tenant | Deploy tenant-specific guards on tenant switch | Assign tenant guards to routes |
| A/B testing | Deploy variant guard, abandon when test ends | β |
| Maintenance mode | Deploy maintenance outpost globally | β |
| Feature flags | Deploy/abandon based on flag changes | Assign/revoke based on flag state |
TIP
For full method signatures, see API Methods. For organizing outposts across modules, see Modular Apps.