Which @angular/* package(s) are relevant/related to the feature request?
core, router
Description
We maintain an open-source Angular meta-framework for building ecommerce. We currently use initialNavigation: 'enabledBlocking' in our SSR application with non-destructive hydration, and it works properly for our needs. However, we’d like to address the following diagnostic message:
NG05001: Configuration error: found both hydration and enabledBlocking initial navigation in the same application, which is a contradiction.
When initialNavigation: enabledBlocking is removed, Angular falls back to INITIAL_NAVIGATION with the value enabledNonBlocking. Therefore, the initial render of the entire component tree starts to happen in parallel with the Router's initial navigation phase. Previously, routing happened first, and only then could the rendering of components start. This means that if any components implicitly expected some side-effects from the initial routing phase to already be finished, they might now encounter a race condition.
The core issue is that hydration requires non-blocking navigation, but we have a legitimate use case that relies on bootstrap-blocking behavior. Specifically, we need to extract URL-based parameters such as auth codes, coupons, and configuration data before they are potentially lost during any redirects.
Some of our features depend on the LOCATION_INITIALIZED promise, which we observed Angular ignores when enableBlocking is not set. This can be seen in the source code, where Angular waits for LOCATION_INITIALIZED only if enabledBlocking is set, as shown at
|
export function withEnabledBlockingInitialNavigation(): EnabledBlockingInitialNavigationFeature { |
|
const providers = [ |
|
{provide: IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, useValue: true}, |
|
{provide: INITIAL_NAVIGATION, useValue: InitialNavigation.EnabledBlocking}, |
|
provideAppInitializer(() => { |
|
const injector = inject(Injector); |
|
const locationInitialized: Promise<any> = injector.get( |
|
LOCATION_INITIALIZED, |
|
Promise.resolve(), |
|
); |
This is a critical change for us and impacts several important functionalities.
We'd prefer to adopt hydration for its performance and UX benefits without having to refactor our entire initialization logic. Also the new diagnostic in Angular 21 (NG05001) has introduced confusion for our community and library users, because it implies the configuration is invalid, but we haven’t observed issues yet.
References:
• Angular issue: Practical consequences of using enabledBlocking with non-destructive hydration (Angular 21 NG05001) #66652
• Angular issue: Show warning when withEnabledBlockingInitialNavigation Is used with provideClientHydration #59624
• Angular PR: feat(platform-browser): Warns on conflicting hydration and blocking #62963
Proposed solution
1. Public API to Dismiss NG05001 Diagnostic
Could the Angular team provide a public API to dismiss or configure this diagnostic? This would allow us to continue using enabledBlocking alongside non-destructive hydration for applications that have legitimate use cases requiring both.
If this approach is viable, we'd be happy to contribute a PR ourselves if the team doesn't have bandwidth for this enhancement. 👍
2. Alternative: Honor LOCATION_INITIALIZED Promise with Non-Blocking Navigation and Hydration
If exposing a public API to dismiss the diagnostic isn't feasible, could Angular take into account the LOCATION_INITIALIZED Promise even when navigation is non-blocking AND hydration is enabled, effectively delaying initial navigation until the Promise resolves?
Our motivation: We need to extract information from the URL before the router processes it and navigation occurs, including:
- Auth nonce & code from 3rd-party login page redirect URLs
- Other async logic from our custom ConfigInitializers that affect various parts of the application
Currently, enabledBlocking provides exactly the bootstrap timing we need, but it's incompatible with hydration.
3. Recommended Angular APIs/Events/Hooks
What Angular APIs, events, or hooks would the team recommend to achieve our goals while maintaining compatibility with non-destructive hydration?
Our requirements are:
- Run custom async initialization logic that may affect routing decisions
- Maintain SSR with non-destructive hydration compatibility
- Achieve similar timing to what enabledBlocking provides (bootstrap blocked until navigation completes), but in a hydration-compatible way
Alternatives considered
The warning message is being ignored because it has not shown any observable effect on our daily operations.
Which @angular/* package(s) are relevant/related to the feature request?
core, router
Description
We maintain an open-source Angular meta-framework for building ecommerce. We currently use
initialNavigation: 'enabledBlocking'in our SSR application with non-destructive hydration, and it works properly for our needs. However, we’d like to address the following diagnostic message:When
initialNavigation: enabledBlockingis removed, Angular falls back toINITIAL_NAVIGATIONwith the valueenabledNonBlocking. Therefore, the initial render of the entire component tree starts to happen in parallel with the Router's initial navigation phase. Previously, routing happened first, and only then could the rendering of components start. This means that if any components implicitly expected some side-effects from the initial routing phase to already be finished, they might now encounter a race condition.The core issue is that hydration requires non-blocking navigation, but we have a legitimate use case that relies on bootstrap-blocking behavior. Specifically, we need to extract URL-based parameters such as auth codes, coupons, and configuration data before they are potentially lost during any redirects.
Some of our features depend on the
LOCATION_INITIALIZEDpromise, which we observed Angular ignores whenenableBlockingis not set. This can be seen in the source code, where Angular waits forLOCATION_INITIALIZEDonly if enabledBlocking is set, as shown atangular/packages/router/src/provide_router.ts
Lines 441 to 450 in d9c980a
This is a critical change for us and impacts several important functionalities.
We'd prefer to adopt hydration for its performance and UX benefits without having to refactor our entire initialization logic. Also the new diagnostic in Angular 21 (NG05001) has introduced confusion for our community and library users, because it implies the configuration is invalid, but we haven’t observed issues yet.
References:
• Angular issue: Practical consequences of using enabledBlocking with non-destructive hydration (Angular 21 NG05001) #66652
• Angular issue: Show warning when withEnabledBlockingInitialNavigation Is used with provideClientHydration #59624
• Angular PR: feat(platform-browser): Warns on conflicting hydration and blocking #62963
Proposed solution
1. Public API to Dismiss NG05001 Diagnostic
Could the Angular team provide a public API to dismiss or configure this diagnostic? This would allow us to continue using
enabledBlockingalongside non-destructive hydration for applications that have legitimate use cases requiring both.If this approach is viable, we'd be happy to contribute a PR ourselves if the team doesn't have bandwidth for this enhancement. 👍
2. Alternative: Honor
LOCATION_INITIALIZEDPromise with Non-Blocking Navigation and HydrationIf exposing a public API to dismiss the diagnostic isn't feasible, could Angular take into account the
LOCATION_INITIALIZEDPromise even when navigation is non-blocking AND hydration is enabled, effectively delaying initial navigation until the Promise resolves?Our motivation: We need to extract information from the URL before the router processes it and navigation occurs, including:
- Auth nonce & code from 3rd-party login page redirect URLs
- Other async logic from our custom ConfigInitializers that affect various parts of the application
Currently, enabledBlocking provides exactly the bootstrap timing we need, but it's incompatible with hydration.
3. Recommended Angular APIs/Events/Hooks
What Angular APIs, events, or hooks would the team recommend to achieve our goals while maintaining compatibility with non-destructive hydration?
Our requirements are:
- Run custom async initialization logic that may affect routing decisions
- Maintain SSR with non-destructive hydration compatibility
- Achieve similar timing to what
enabledBlockingprovides (bootstrap blocked until navigation completes), but in a hydration-compatible wayAlternatives considered
The warning message is being ignored because it has not shown any observable effect on our daily operations.