-
Notifications
You must be signed in to change notification settings - Fork 27.1k
Open
Labels
area: routergemini-triagedLabel noting that an issue has been triaged by geminiLabel noting that an issue has been triaged by gemini
Milestone
Description
Which @angular/* package(s) are relevant/related to the feature request?
Problem
In microfrontend architectures using Module Federation, Angular
applications often expose either routes or standalone components from
remote builds.
A common real-world requirement is to fetch runtime configuration from
a backend before initializing routes or components (e.g., feature
flags, dynamic route definitions, environment-specific endpoints).
Currently, Angular provides:
APP_INITIALIZER--- only runs at application bootstrap (too early
/ global)- Route guards and resolvers --- run after route matching
- Route providers --- scoped DI, but no async blocking mechanism
This creates a gap when:
- Routes depend on async configuration
- Routes must be dynamically constructed at runtime
- Application must support deep linking (page refresh on nested
routes)
Current Limitation
If routes are built dynamically from fetched configuration:
- On page refresh (deep link), Angular router attempts to match routes
before configuration is loaded - Since routes are not yet registered → navigation falls through to
wildcard (404)
Guards/resolvers do not solve this because:
- They execute after route matching
- They cannot prevent router from failing to recognize a route
APP_INITIALIZER is also not suitable because:
- It is global (not route-scoped)
- It does not integrate cleanly with lazy-loaded MFEs
- It forces all configuration to load upfront, even when not needed
Proposed Solution
Introduce a route-level async initializer that runs before route
matching and activation, allowing async setup of route configuration.
Proposed solution
Example API
{
path: '',
providers: [
provideRouteInitializer(async () => {
const configService = inject(ConfigService);
const routes = await configService.getRoutes();
const router = inject(Router);
router.resetConfig(routes);
})
],
loadChildren: () => import('./remote.routes')
}Alternatives considered
no idea tbh.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area: routergemini-triagedLabel noting that an issue has been triaged by geminiLabel noting that an issue has been triaged by gemini