-
Notifications
You must be signed in to change notification settings - Fork 27.1k
Hydration error when component's content is re-projected using ng-template #53276
Copy link
Copy link
Closed
Labels
P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentAn issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: coreIssues related to the framework runtimeIssues related to the framework runtimecore: hydrationhotlist: components teamRelated to Angular CDK or Angular MaterialRelated to Angular CDK or Angular Materialstate: has PR
Milestone
Description
Angular Material has several cases where there's a parent component and a child component meant to be used together. The child has a template like <ng-template #content><ng-content/></ng-template> while the parent iterates over the children and projects their content using ngTemplateOutlet. This is a bit of a convoluted way of rendering, but it has allowed us to implement some complex layouts while keeping a friendly public API. Moving away from this pattern will be difficult without breaking changes so ideally this should be handled at the framework level. The issue can be reproduced by adding the following test to packages/platform-server/test/hydration_spec.ts:
it('should allow re-projection of child content', async () => {
@Component({
standalone: true,
selector: 'mat-step',
template: `
<ng-template #content><ng-content/></ng-template>
`,
})
class MatStep {
@ViewChild('content', {read: TemplateRef}) content!: TemplateRef<any>;
}
@Component({
standalone: true,
selector: 'mat-stepper',
imports: [NgTemplateOutlet],
template: `
@for (step of steps; track step) {
<ng-container [ngTemplateOutlet]="step.content"/>
}
`,
})
class MatStepper {
@ContentChildren(MatStep) steps!: QueryList<MatStep>;
}
@Component({
standalone: true,
imports: [MatStepper, MatStep],
selector: 'app',
template: `
<mat-stepper>
<mat-step>One</mat-step>
<mat-step>Two</mat-step>
<mat-step>Three</mat-step>
</mat-stepper>
`,
})
class App {
}
const html = await ssr(App);
const ssrContents = getAppContents(html);
expect(ssrContents).toContain('<app ngh');
resetTViewsFor(App, MatStepper);
const appRef = await hydrate(html, App);
const compRef = getComponentRef<App>(appRef);
appRef.tick();
const clientRootNode = compRef.location.nativeElement;
verifyAllNodesClaimedForHydration(clientRootNode);
verifyClientAndSSRContentsMatch(ssrContents, clientRootNode);
});Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentAn issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: coreIssues related to the framework runtimeIssues related to the framework runtimecore: hydrationhotlist: components teamRelated to Angular CDK or Angular MaterialRelated to Angular CDK or Angular Materialstate: has PR