Create Components at Runtime
Dynamic Components
Use ViewContainerRef.createComponent to insert a component programmatically — useful for dialogs, popovers, and plugin systems.
What you'll learn
- Inject ViewContainerRef
- Call createComponent(MyComponent)
- Set inputs and listen to outputs programmatically
Most components are placed declaratively in a template. Sometimes you want to spawn one at runtime — a toast, a modal, an editor plugin. That is a dynamic component.
Insert at a Location
import { Component, ViewContainerRef, inject } from '@angular/core';
import { ToastComponent } from './toast.component';
@Component({
selector: 'app-root',
standalone: true,
template: `<button (click)="show()">Show toast</button>`,
})
export class AppComponent {
private vcr = inject(ViewContainerRef);
show() {
const ref = this.vcr.createComponent(ToastComponent);
ref.setInput('message', 'Saved!');
ref.instance.dismissed.subscribe(() => ref.destroy());
setTimeout(() => ref.destroy(), 3000);
}
} ViewContainerRef is a marker for a position in the DOM. createComponent() returns a ComponentRef you can use to drive the instance.
Setting Inputs and Reading Outputs
ref.setInput('name', value)— works for both signal inputs and legacy@Input(). Triggers change detection.ref.instance.someOutput.subscribe(fn)— outputs are still observable-like.ref.destroy()— removes the component and runsngOnDestroy.
Anchored ViewContainerRef
Often you want the dynamic component to land at a specific spot in your template, not at the host. Use a template anchor.
<ng-template #anchor /> import { viewChild, ViewContainerRef } from '@angular/core';
anchor = viewChild.required('anchor', { read: ViewContainerRef });
show() {
const ref = this.anchor().createComponent(ToastComponent);
ref.setInput('message', 'Hello');
} This is exactly how Angular CDK Overlay and most modal libraries work under the hood.
Two Form APIs — Pick One →