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 programmatically. This is helpful for situations when a component is unknown initially (thus can not be referenced in a template directly) and it depends on some conditions.

There are two main ways to render a component programmatically: in a template using NgComponentOutlet, or in your TypeScript code using ViewContainerRef.

HELPFUL: for lazy-loading use-cases (for example if you want to delay loading of a heavy component), consider using the built-in @defer feature instead. The @defer feature allows the code of any components, directives, and pipes inside the @defer block to be extracted into separate JavaScript chunks automatically and loaded only when necessary, based on the configured triggers.

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 { user = input.required<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 { private viewContainer = inject(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

HELPFUL: if you want to lazy-load some components, you may consider using the built-in @defer feature instead.

If your use-case is not covered by the @defer feature, you can use either NgComponentOutlet or ViewContainerRef 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(): AdvancedSettings} | undefined; async loadAdvanced() { const { AdvancedSettings } = await import('path/to/advanced_settings.js'); this.advancedSettings = AdvancedSettings; }}

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