Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion packages/angular-server/src/ionic-server-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,17 @@ export class IonicServerModule {}
export function hydrateIonicComponents(doc: any, appId: any) {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
return () => {
const supportsNativeAttachShadow =
typeof doc?.createElement?.('div')?.attachShadow === 'function';

return hydrateDocument(doc, {
clientHydrateAnnotations: false,
// Fallback for SSR DOMs (e.g. Domino) that do not implement attachShadow.
...(supportsNativeAttachShadow
? { clientHydrateAnnotations: false }
: {
serializeShadowRoot: 'scoped',
clientHydrateAnnotations: true,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
clientHydrateAnnotations: true,
clientHydrateAnnotations: false,

I think this should be false rather than true. I ran renderToString on Stencil 4.43.5 (what main ships) with both values: with true the serializer injects <!--r.1-->/<!--r.2--> root hydrate markers as siblings right before <ion-button>, which are the exact nodes traced to Angular client hydration throwing hasAttribute is not a function on Angular 18. With false those markers are gone, and there's still only one native <button>, so the duplicate-internals symptom you originally needed true to avoid doesn't come back on 4.43.5 (that was a pre-4.40 Stencil bug that's since been fixed).

So false gives no server crash, no duplicate internals, and no hydration-breaking markers, which should work with provideClientHydration() across Angular versions rather than only without it. One caveat: I verified this at the Stencil serialization layer in Node, not with a live Angular hydration runtime, so it'd be worth confirming in the ng18 repro with provideClientHydration() enabled before merging.

}),
excludeComponents: [
// overlays
'ion-action-sheet',
Expand Down