Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Angular’s NG8116 means a standalone component’s template uses a custom structural directive without importing that directive. Import the directive class and add it to the component’s imports array. This is an Angular template-scope issue, not a missing HTML feature.
What does NG8116 mean in Angular?
NG8116 is an Angular extended diagnostic for a custom structural directive used in a standalone component template but missing from that component’s imports. For example, if a template contains *select, Angular needs the directive that defines select in the component’s template scope. See Angular’s NG8116 documentation.
The asterisk can make the syntax look like an ordinary HTML attribute, but it is Angular syntax. Angular expands a structural directive’s * shorthand into an <ng-template> that hosts the directive and wraps the original element and its contents. The shorthand’s keys map to directive inputs; for instance, *myDir="let item of [1,2,3]" expands to a template using myDir and its myDirOf input. NG8116 flags a missing directive import, while malformed microsyntax or incompatible inputs can produce separate template errors. Angular explains the shorthand in its structural directives guide.
How do you fix NG8116?
- Identify the selector. Find the custom directive used after the asterisk, such as
*selector*featureFlag. - Find the directive class. Locate the class that defines that selector. If it comes from a library or shared package, use the package’s actual exported symbol and import path; there is no universal package path.
- Add the class to the standalone component. Import the symbol in the TypeScript file, then list it in the component’s
importsmetadata. - Rebuild with template checking enabled. Extended diagnostics require
strictTemplates; NG8116 has no additional prerequisite.
Angular’s documented example follows this pattern:
#1 Best Overall
import { Component } from '@angular/core';
import { SelectDirective } from 'my-directives';
@Component({
imports: [SelectDirective],
template: `<p *select="let data; from: source">{{ data }}</p>`,
})
class MyComponent {}
Replace SelectDirective and my-directives with the class and import path used by your project. Confirm that the imported symbol is the directive class itself and that it appears in the relevant standalone component’s imports array.
Why does a standalone component need the import?
A standalone component declares which directives and other Angular dependencies are available to its template through its own imports metadata. A directive existing elsewhere in the project does not, by itself, place it in this component’s template scope.
Rank #2
Without the directive import, Angular documents that using a structural directive “will fail at runtime, as Angular attempts to bind to a select property of the HTML element, which does not exist.” The import gives Angular the directive that understands the selector and its inputs; it does not add a new native HTML attribute.
How is NG8116 different from NG8103?
Check which directive the template actually uses. NG8116 concerns a missing custom structural directive; NG8103 concerns missing imports for known built-in control-flow directives such as *ngIf, *ngFor, or *ngSwitch in a standalone component. The similar symptom does not make the diagnostic codes interchangeable.
Rank #3
| Template directive | Relevant diagnostic | Typical path |
|---|---|---|
Custom structural directive, such as *select |
NG8116 | Import that directive class into the standalone component. |
Built-in directive, such as *ngIf, *ngFor, or *ngSwitch |
NG8103 | Import the specific built-in directive or CommonModule; for NgIf and NgFor use cases, consider the current @if and @for control-flow blocks. |
Angular’s extended diagnostics overview describes NG8103’s built-in-directive case. The current API pages mark NgIf and NgFor deprecated since v20.0 and recommend @if and @for, respectively; check the NgIf API and NgFor API for the current guidance. Those recommendations apply to the built-in use cases, not to a custom directive reported by NG8116.
What structural-directive syntax issues should you check separately?
Only one asterisk shorthand per element
Angular permits only one structural directive using * shorthand on a given element. If two structural behaviors need to apply to the same content, nest the template structure instead of putting two asterisk directives on that element. An <ng-container> can act as the wrapper without adding a DOM element; see Angular’s ng-container API.
Rank #4
A bare ng-template does not render content
The shorthand expansion helps explain what Angular does, but replacing the shorthand with a bare <ng-template> is not automatically a repair. Angular does not render an <ng-template> by default; a structural directive or another Angular API must instruct it to create the embedded view. See the ng-template API.
Can you suppress NG8116?
Angular extended diagnostics are warnings by default, and a project can configure a diagnostic as an error or suppress it. The NG8116 documentation shows this suppression setting:
{
"angularCompilerOptions": {
"extendedDiagnostics": {
"checks": {
"missingStructuralDirective": "suppress"
}
}
}
}
Suppression hides the diagnostic; it does not make the missing directive available in the template. Use it only for an intentional exception, not as a substitute for importing the directive.
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.

