The Angular error ng8116 means the compiler cannot find a structural directive you referenced in a template — typically because the directive is not imported, not declared, or the import path is wrong. To fix it, ensure the directive is properly imported in your standalone component or declared in the appropriate NgModule, then re-run your build.
Background: What Is a Structural Directive?
Structural directives in Angular change the layout of the DOM by adding, removing, or manipulating elements. The most common ones are *ngIf, *ngFor, and *ngSwitch. They are called “structural” because they affect the structure of the view, not just the appearance of a single element. The asterisk (*) is shorthand syntax that Angular expands into an <ng-template> wrapper.
When you write *ngIf="condition", Angular internally transforms it to:
<ng-template [ngIf]="condition"><div>...</div></ng-template>
The directive itself is a class decorated with @Directive that has a selector like [ngIf]. For Angular to recognize it in a template, the directive must be part of the compilation context of that component.
Why Does ng8116 Occur?
The ng8116 error is a compiler diagnostic that appears when the Angular compiler encounters a template that uses a structural directive it cannot resolve. This can happen for several reasons:
- Missing import in a standalone component — you used
*ngIfbut didn’t importCommonModuleorNgIf. - Not declared in an NgModule — the directive is not listed in the
declarationsarray of the module that declares your component. - Wrong import path — you imported a directive from an incorrect module or a custom directive from a non-existent file.
- Typo in selector — you wrote
*ngif(lowercase) instead of*ngIf, or misspelled a custom directive name. - Directive not exported — you imported a module that does not re-export the directive you need.
In older Angular versions (pre-standalone), the most common cause was forgetting to add CommonModule to the imports array of your feature module. In modern Angular (v14+), standalone components require explicit imports of any directive you use.
How to Fix ng8116
Follow these steps in order. The fix depends on whether you are using standalone components or NgModules.
For Standalone Components
- Open the component file where the error occurs.
- Look at the
importsarray in the@Componentdecorator. - If you are using built-in directives like
*ngIfor*ngFor, addCommonModuleto that array:
import { CommonModule } from '@angular/common';
@Component({
standalone: true,
imports: [CommonModule],
// ...
})
export class MyComponent {}
Alternatively, you can import only the specific directive: imports: [NgIf, NgFor] from @angular/common. For a custom structural directive, import the directive class itself and add it to the imports array.
For NgModule-Based Applications
- Locate the module that declares your component (e.g.,
AppModuleor a feature module). - Ensure
CommonModuleis in theimportsarray of that module. If not, add it. - If you are using a custom directive, verify it is declared in the
declarationsarray of the same module or imported via a shared module that exports it.
import { CommonModule } from '@angular/common';
import { MyCustomDirective } from './my-custom.directive';
@NgModule({
declarations: [MyComponent, MyCustomDirective],
imports: [CommonModule],
})
export class MyModule {}
Check for Typos
Angular is case-sensitive. The built-in directives are *ngIf, *ngFor, and *ngSwitch. A common mistake is writing *ngif or *ngFor with a space. Also, ensure your custom directive selector matches exactly what you use in the template.
Common Misconception: Is ng8116 the Same as NG0303?
No. NG0303 is a runtime error that occurs when the template is compiled but the directive is not found at runtime. ng8116 is a compile-time error that prevents the build from succeeding. You might see ng8116 first, and after fixing it, NG0303 could appear if the directive is not properly provided at runtime (e.g., in lazy-loaded modules). The fixes are similar, but ng8116 is caught earlier in the pipeline.
How to Prevent ng8116 in Future Projects
- Use standalone components — they force you to explicitly import what you use, making missing imports obvious.
- Create shared modules for custom directives and export them, so you only import one module.
- Use the Angular language service in your IDE — it highlights missing imports before you even run the build.
- Run
ng buildin watch mode during development to catch errors early.
Alternatives and Advanced Cases
If you are using a third-party library that provides structural directives (e.g., *ngxPermissionsOnly from ngx-permissions), the fix is to import the library’s module in your module or standalone component. If you are writing a custom structural directive, ensure you import the Directive and TemplateRef from @angular/core and that you export the directive class from its module.
For complex templates, you can also use the longhand <ng-template> syntax instead of the asterisk shorthand. This sometimes gives clearer error messages because the directive binding is explicit.
Frequently Asked Questions
Why do I get ng8116 even though I imported CommonModule?
Double-check that the import is in the correct component. If you have multiple components in the same file, ensure the imports array is on the component that actually uses the directive. Also, verify that the import path is correct — a common mistake is importing from @angular/core instead of @angular/common.
Can ng8116 be caused by a custom structural directive?
Yes. If you created a custom directive and used it in a template but forgot to declare it in the module or add it to the standalone component’s imports, you will see ng8116. Make sure the directive class is exported and imported correctly.
Does ng8116 appear in Angular 17 or 18?
Yes, the error code remains the same across recent Angular versions. The fix is identical, though standalone components have become the default in new projects since Angular 15, so the import approach is more common now.
What if I see ng8116 in a library project?
In a library, you need to ensure that the directive is exported from the public API (the public-api.ts file) and that the consuming application imports the module. Also, verify that the library’s module imports CommonModule if it uses built-in directives internally.
Is there a way to auto-fix ng8116?
Some IDEs (like Visual Studio Code with the Angular Language Service) offer a quick fix to add missing imports. You can also use the Angular CLI’s ng generate commands to scaffold components and modules, which reduces the chance of missing imports.
Why does the error message not tell me which directive is missing?
The error message usually includes the selector of the missing directive, e.g., “Can’t bind to ‘ngIf’ since it isn’t a known property of ‘div’.” That is the clue. Look for the selector name in the message and then check if that directive is imported.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Mac Start Up Automatically After Power Failure?
- Expose Self-Hosted Service Securely Without Cloudflare Tunnel
- Nano Delivery for Functional Foods: What It Can and Can’t Do4.00
- Disable Apple Watch Turn-by-Turn Vibration While Driving
- Convert Play FLAC in iTunes: Full Guide
- Soda Foundation Charter: What It Means