In-depth Guides
Components

Programmatically rendering components

Tip: This guide assumes you've already read the Essentials Guide. Read that first if you're new to Angular.

In addition to using a component directly in a template, you can also dynamically render components. There are two main ways to dynamically render a component: in a template with NgComponentOutlet, or in your TypeScript code with ViewContainerRef.

Using NgComponentOutlet

NgComponentOutlet is a structural directive that dynamically renders a given component in a template.

      
@Component({ ... })
export class AdminBio { /* ... */ }
@Component({ ... })
export class StandardBio { /* ... */ }
@Component({
...,
template: `
<p>Profile for {{user.name}}</p>
<ng-container *ngComponentOutlet="getBioComponent()" /> `
})
export class CustomDialog {
@Input() user: User;
getBioComponent() {
return this.user.isAdmin ? AdminBio : StandardBio;
}
}

See the NgComponentOutlet API reference for more information on the directive's capabilities.

Using ViewContainerRef

A view container is a node in Angular's component tree that can contain content. Any component or directive can inject ViewContainerRef to get a reference to a view container corresponding to that component or directive's location in the DOM.

You can use the createComponentmethod on ViewContainerRef to dynamically create and render a component. When you create a new component with a ViewContainerRef, Angular appends it into the DOM as the next sibling of the component or directive that injected the ViewContainerRef.

      
@Component({
selector: 'leaf-content',
template: `
This is the leaf content
`,
})
export class LeafContent {}
@Component({
selector: 'outer-container',
template: `
<p>This is the start of the outer container</p>
<inner-item />
<p>This is the end of the outer container</p>
`,
})
export class OuterContainer {}
@Component({
selector: 'inner-item',
template: `
<button (click)="loadContent()">Load content</button>
`,
})
export class InnerItem {
constructor(private viewContainer: ViewContainerRef) {}
loadContent() {
this.viewContainer.createComponent(LeafContent);
}
}

In the example above, clicking the "Load content" button results in the following DOM structure

      
<outer-container>
<p>This is the start of the outer container</p>
<inner-item>
<button>Load content</button>
</inner-item>
<leaf-content>This is the leaf content</leaf-content>
<p>This is the end of the outer container</p>
</outer-container>

Lazy-loading components

You can use both of the approaches described above, NgComponentOutlet and ViewContainerRef, to render components that are lazy-loaded with a standard JavaScript dynamic import.

      
@Component({
...,
template: `
<section>
<h2>Basic settings</h2>
<basic-settings />
</section>
<section>
<h2>Advanced settings</h2>
<button (click)="loadAdvanced()" *ngIf="!advancedSettings">
Load advanced settings
</button>
<ng-container *ngComponentOutlet="advancedSettings" />
</section>`
})
export class AdminSettings {
advancedSettings: {new(): AdminSettings} | undefined;
async loadAdvanced() {
this.advancedSettings = await import('path/to/advanced_settings.js');
}
}

The example above loads and displays the AdvancedSettings upon receiving a button click.