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:
<input><select>Custom form components
…all loaded during runtime.
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
If you know the structure at compile time → Use ng-content
If the structure changes at runtime → Use ViewContainerRef
10. Combining Both (Real Enterprise Example)
You want:
Tabs with custom content (projection)
Each tab dynamically loads a component when selected (ViewContainerRef)
This gives:
Performance (lazy loading)
Flexibility (content projection)
Dynamic rendering
11. Best Practices
Content Projection
Use
selectfor multi-slot structureAvoid deeply nested
ng-contentUse it for visual flexibility, not dynamic behavior
ViewContainerRef
Always call
.clear()before creating componentsRemove views when navigation changes
Prefer Angular’s newer API
createComponent()instead of oldComponentFactoryResolverUse
ng-templatewith 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:
Highly reusable UI components
Dynamic dashboards
Form builders
Modal systems
Enterprise-level UI frameworks

Join the conversation! Your thoughts help the community grow.