Angular reports NG8011 when a control-flow block contains more than one root node and Angular cannot match the block to a named <ng-content> slot. Put the grouped nodes inside an <ng-container ngProjectAs="[slot-selector]">, or split them so each control-flow block has one projectable root. See Angular’s NG8011 error guide for the rule and examples.
Why NG8011 happens
Content projection matches content supplied by a parent with the receiving component’s <ng-content> placeholders. For example, a component might define a named title slot and a default slot:
As an Amazon Associate I earn from qualifying purchases.
<ng-content select="[card-title]" />
<ng-content />
<ng-content> is a compile-time placeholder, not a runtime DOM node. Angular’s content-projection guide explains how projected content is matched to these placeholders.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Built-in control-flow blocks such as @if emulate the projection behavior of *ngIf and *ngFor: the block projects the element to which it is applied. That rule works when the block has one root node. With multiple roots, Angular cannot reliably match the block to a named slot, so content intended for that slot may instead appear in the default slot.
#1 Best Overall
This parent template has two roots inside one block:
<app-card>
@if (showTitle) {
<h2 card-title>Title</h2>
<p>Subtitle</p>
}
</app-card>
Text is a root node too. Angular notes that stray text beside the projected element can cause the same problem; if the component containing the block sets preserveWhitespaces: true, whitespace can count as a root as well. Check the whole block, not just its visible elements.
Rank #2
Choose a template repair
Keep the group together with ngProjectAs
Use this when the nodes belong together and should all go to the same named slot. Put them inside an <ng-container> and alias that container to the slot selector:
<app-card>
@if (showTitle) {
<ng-container ngProjectAs="[card-title]">
<h2>Title</h2>
<p>Subtitle</p>
</ng-container>
}
</app-card>
The value of ngProjectAs must match the receiving slot selector. It is static and cannot be bound to a dynamic expression, as documented in Angular’s ng-content API.
Rank #3
Split the content into one-root blocks
Use this when each node should be projected or matched independently. Give each control-flow block a single projectable root:
<app-card>
@if (showTitle) {
<h2 card-title>Title</h2>
}
@if (showTitle) {
<p>Subtitle</p>
}
</app-card>
Here the heading can match the named slot on its own. The paragraph has no card-title attribute, so it remains eligible for the default slot.
Rank #4
Do not put the receiving slot behind control flow
NG8011 concerns the projected content supplied by the parent. A different but related mistake is conditionally rendering the receiver’s <ng-content> placeholder:
Recommended Free Tools
@if (showTitle) {
<ng-content select="[card-title]" />
}
Angular advises against conditionally including <ng-content> with @if, @for, or @switch: content projected to the placeholder is instantiated even when that placeholder is hidden. If the receiving component needs to control whether content is rendered, follow Angular’s template-fragment guidance instead.
Angular version and diagnostic suppression
Built-in control-flow syntax is available from Angular v17. Angular’s migration guide documents the schematic ng generate @angular/core:control-flow, including its --path and --format options. These built-in blocks do not require importing CommonModule.
An Angular repository issue reported NG8011 around projected <mat-error> content in Angular 17.1.0 with CLI 17.1.1. That is a dated report, not evidence about every Angular release. The report also mentions suppressing the diagnostic with extendedDiagnostics.checks.controlFlowPreventingContentProjection = "suppress". Suppression only hides the warning; it does not change projection behavior or fix the template, so use the documented structural repairs when appropriate. See Angular issue #54077.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




