Content projection and ViewContainerRef are two of the most powerful Angular features that allow you to build flexible, reusable, and dynamic UI components.
This article takes you through both concepts with simple explanations, real-life case studies, and practical examples.
1. What Is Content Projection?
Content projection allows you to insert external content into a component’s view.
This is how Angular enables reusable UI components with customizable content (similar to slots in Web Components).
You use ng-content to mark where projected content should appear.
2. Basic Example of Content Projection
Create a reusable card component.
card.component.html
<div class="card">
<div class="card-header">
<ng-content select="[card-title]"></ng-content>
</div>
<div class="card-body">
<ng-content></ng-content>
</div>
</div>
Using the component
<app-card>
<h3 card-title>Login</h3>
<p>Please enter your email and password</p>
</app-card>
This gives you a flexible component where the parent decides what content goes inside.
3. Case Study — Building a Reusable Modal Component
This modal can accept:
Header content
Body content
Footer content
modal.component.html
<div class="modal">
<div class="modal-header">
<ng-content select="[modal-header]"></ng-content>
</div>
<div class="modal-body">
<ng-content select="[modal-body]"></ng-content>
</div>
<div class="modal-footer">
<ng-content select="[modal-footer]"></ng-content>
</div>
</div>
Usage
<app-modal>
<h2 modal-header>Confirm Delete</h2>
<p modal-body>Are you sure?</p>
<button modal-footer>Yes</button>
</app-modal>
This is a perfect example of "slot-based design".
4. Single Slot vs Multi-Slot Projection
Single slot
<ng-content></ng-content>
Multi-slot using selectors
<ng-content select=".header"></ng-content>
<ng-content select=".body"></ng-content>
Angular chooses the <ng-content> slot based on CSS-like selectors.
5. What Content Projection Cannot Do
Understanding limitations helps decide when to use ViewContainerRef.
Content projection cannot:
Dynamically create or remove components
Modify projected content
Load components based on logic
Insert components programmatically
For those use-cases, we use ViewContainerRef.
6. Introduction to ViewContainerRef
ViewContainerRef allows you to:
Dynamically create components
Insert or remove them at runtime
Control the rendering programmatically
It is commonly used with:
Dynamic forms
Dynamic modals
Portal-like components
Component factories
7. Basic Example of ViewContainerRef
Directive to mark insertion point
@Directive({
selector: '[dynamicHost]',
})
export class DynamicHostDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
Component that dynamically loads another component
@Component({
selector: 'app-dynamic-loader',
template: `<ng-template dynamicHost></ng-template>`,
})
export class DynamicLoaderComponent implements AfterViewInit {
@ViewChild(DynamicHostDirective, { static: true })
host!: DynamicHostDirective;
constructor(private resolver: ComponentFactoryResolver) {}
ngAfterViewInit() {
const viewContainer = this.host.viewContainerRef;
viewContainer.clear();
const factory = this.resolver.resolveComponentFactory(HelloComponent);
viewContainer.createComponent(factory);
}
}
Dynamically added component
@Component({
selector: 'app-hello',
template: `<p>Hello from dynamic component!</p>`,
})
export class HelloComponent {}
This displays a component without being in the template statically.
8. Case Study — Dynamic Form Builder
Many enterprise apps require:
Forms that change based on user role
Fields coming from database metadata
Adding/removing fields at runtime
This is where ViewContainerRef shines.
Insert dynamic input fields
addField(fieldType: any) {
const container = this.dynamicHost.viewContainerRef;
const componentRef = container.createComponent(fieldType);
}
You can dynamically add:
9. Content Projection vs ViewContainerRef — When to Use What
| Feature | Content Projection | ViewContainerRef |
|---|
| Reusable layout templates | Yes | No |
| Dynamic UI creation | No | Yes |
| Parent provides content | Yes | No |
| Programmatic control | No | Yes |
| Better for | Cards, modals, tabs, layouts | Dynamic forms, dynamic pages |
| Managed by | Template | Component code |
Rule of Thumb
10. Combining Both (Real Enterprise Example)
You want:
This gives:
11. Best Practices
Content Projection
Use select for multi-slot structure
Avoid deeply nested ng-content
Use it for visual flexibility, not dynamic behavior
ViewContainerRef
Always call .clear() before creating components
Remove views when navigation changes
Prefer Angular’s newer API createComponent() instead of old ComponentFactoryResolver
Use ng-template with a directive to mark insertion points
12. Summary
Content Projection is used for static but flexible templates, while ViewContainerRef is used for dynamic component rendering.
Together, they help you build: