Skip to content

Skipping hydration on i18n nodes breaks hydration #57105

@henry-alakazhang

Description

@henry-alakazhang

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

When enabling hydration + i18n support, adding i18n to elements that have hydration skipped breaks hydration on the client side due to missing root nodes.

The actual error thrown varies based on where the skipHydration attribute and i18n nodes are:

Attributes on the same component:

<app-text i18n ngSkipHydration> Text </app-text>

throws ERROR Error: ASSERTION ERROR: Expected root i18n node during hydration [Expected=> null != null <=Actual]

ngSkipHydration attribute on the parent of an i18n node:

<app-text ngSkipHydration>
  <div i18n>Text</div>
</app-text>

throws TypeError: rootNode is null

ngSkipHydration hostbound attribute on the parent of an i18n node: (ie. app-unhydrated-text has @HostBinding('attr.ngSkipHydration'))

<app-unhydrated-text>
  <div i18n>Title!</div>
</app-unhydrated-text>

throws NG0502: During hydration Angular was unable to locate a node using the "firstChild" path, starting from the <app-unhydrated-text ngskiphydration="true">…</app-unhydrated-text> node.

The only combination that works is applying i18n outside the area that's skipped:

<div i18n>
  <app-text ngSkipHydration> Text </app-text>
</div>

This only applies to i18n nodes in the same template as the elements which have hydration skipped. i18n nodes deeper into the tree are also fine (ie. here, app-has-i18n has i18n tags in its template)

<app-has-i18n ngSkipHydration />

Please provide a link to a minimal reproduction of the bug

https://github.com/henry-alakazhang/angular-i18n-skiphydration-repro

Please provide the exception or error you saw

No response

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 18.1.1
Node: 18.20.3
Package Manager: yarn 1.22.19
OS: darwin arm64

Angular: 18.1.1
... animations, cli, common, compiler, compiler-cli, core, forms
... localize, platform-browser, platform-browser-dynamic
... platform-server, router, ssr

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1801.1
@angular-devkit/build-angular   18.1.1
@angular-devkit/core            18.1.1
@angular-devkit/schematics      18.1.1
@schematics/angular             18.1.1
rxjs                            7.8.1
typescript                      5.5.4
zone.js                         0.14.8

Anything else?

I fiddled a bit with the code and adding an if (isInSkipHydrationBlock()) guard inside prepareprepareI18nBlockForHydrationImpl in hydration/i18n.ts stops the issue from happening (and the page seems to render / hydrate correctly). Don't have the context of the conventions/though to know whether that's the right solution and/or would have any side effects

Metadata

Metadata

Assignees

Labels

P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: coreIssues related to the framework runtimearea: i18nIssues related to localization and internationalizationbugcore: hydrationstate: has PR

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions