Introduction
Angular standalone components (introduced in Angular 14) can be used without NgModules, but when mixing standalone and module-based components, the standalone component must be properly imported into the module that declares or uses it. When this is misconfigured, the component is not recognized:
Error: 'app-user-profile' is not a known element:
1. If 'app-user-profile' is an Angular component, then verify that it is part of this module.
2. If 'app-user-profile' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to this module.Symptoms
- Template error: "is not a known element" for a standalone component
- Standalone component renders in its own route but not when used as a child component
- Component works when used directly in a standalone bootstrap but not in an NgModule
- Error occurs after converting a component to standalone
- Component imports work in one module but not another
Common Causes
- Standalone component not added to the
importsarray of the consuming NgModule - Component has
standalone: falsebut is being treated as standalone - Importing the component file but the export name does not match
- Circular imports between standalone component and NgModule
- Standalone component's own imports (CommonModule, etc.) are missing
Step-by-Step Fix
- 1.Import the standalone component in the NgModule:
- 2.```typescript
- 3.// user-profile.component.ts (standalone)
- 4.@Component({
- 5.selector: 'app-user-profile',
- 6.standalone: true,
- 7.imports: [CommonModule],
- 8.template:
<div class="profile">{{ user.name }}</div>, - 9.})
- 10.export class UserProfileComponent {
- 11.@Input() user: any;
- 12.}
// dashboard.module.ts (NgModule that uses the standalone component) @NgModule({ declarations: [DashboardComponent], imports: [ CommonModule, UserProfileComponent, // Add standalone component here ], }) export class DashboardModule {} ```
- 1.Verify the component is correctly configured as standalone:
- 2.```typescript
- 3.@Component({
- 4.selector: 'app-widget',
- 5.standalone: true, // Must be true
- 6.imports: [CommonModule, MatButtonModule],
- 7.template:
<mat-button>Click</mat-button>, - 8.})
- 9.export class WidgetComponent {}
- 10.
` - 11.Handle standalone components in lazy loaded routes:
- 12.```typescript
- 13.// app.routes.ts
- 14.const routes: Routes = [
- 15.{
- 16.path: 'settings',
- 17.loadComponent: () => import('./settings/settings.component')
- 18..then(m => m.SettingsComponent), // Standalone component
- 19.},
- 20.];
- 21.
` - 22.For standalone components importing other standalone components:
- 23.```typescript
- 24.@Component({
- 25.selector: 'app-dashboard',
- 26.standalone: true,
- 27.imports: [
- 28.CommonModule,
- 29.UserProfileComponent, // Another standalone component
- 30.WidgetComponent, // Another standalone component
- 31.],
- 32.template: `
- 33.<app-user-profile [user]="currentUser"></app-user-profile>
- 34.<app-widget></app-widget>
- 35.`,
- 36.})
- 37.export class DashboardComponent {}
- 38.
`
Prevention
- Always include
standalone: truein the component decorator for standalone components - Add standalone components to the
importsarray of the consuming NgModule, notdeclarations - Use
loadComponentfor lazy loading standalone components instead ofloadChildren - Keep a consistent naming convention: standalone components should be clearly identifiable
- Document which components are standalone vs module-based in your component registry
- Use Angular's schematic to generate standalone components:
ng generate component --standalone - Test standalone components both in isolation and when imported into NgModules
- Run
ng buildafter converting components to standalone to verify all imports are correct