Content Projection in Angular is a powerful feature that allows you to pass content into a component from the parent component’s template. This can be incredibly useful for creating reusable components that can be customized with different content based on the specific use case.
In this tutorial, we will discuss the basics of content projection in Angular, as well as some advanced techniques for handling more complex scenarios.
What is Content Projection?
Content projection in Angular is achieved using the <ng-content>
tag. This tag acts as a placeholder inside the template of a component, where content from the parent component can be inserted.
Here’s a simple example to illustrate content projection:
// parent.component.html
<app-child>
<h1>Hello, world!</h1>
</app-child>
// child.component.html
<div>
<ng-content></ng-content>
</div>
In this example, the app-child
component has a <ng-content>
tag in its template. When the app-child
component is used in the parent.component.html
template with the <h1>
element inside, the content of the <h1>
element will be projected into the <ng-content>
tag in the child.component.html
template.
Basic Usage of Content Projection
Let’s dive into the basic usage of content projection in Angular.
- Create a new component using Angular CLI:
ng generate component my-component
- Update the template of the
my-component
component (my-component.component.html
) to include an<ng-content>
tag:
<div>
<ng-content></ng-content>
</div>
- Use the
my-component
component in the parent component’s template (app.component.html
):
<app-my-component>
<h1>Hello, world!</h1>
</app-my-component>
In this example, the content within the <h1>
element in app.component.html
will be projected into the <ng-content>
tag in my-component.component.html
.
Handling Multiple Content Projections
You can use multiple <ng-content>
tags in a component to handle different types of content projection. Here’s an example:
// my-component.component.html
<div>
<ng-content select="header"></ng-content>
<ng-content select="main"></ng-content>
</div>
// app.component.html
<app-my-component>
<header><h1>Hello, world!</h1></header>
<main><p>Lorem ipsum dolor sit amet.</p></main>
</app-my-component>
In this example, the content within the <header>
and <main>
elements in app.component.html
will be projected into the <ng-content>
tags with the corresponding select
attribute in my-component.component.html
.
Advanced Techniques
Content projection can be used in more complex scenarios to enable behavior like transclusion, slot-based content, and dynamic content projection.
- Transclude content with a default template:
// my-component.component.html
<div>
<ng-content></ng-content>
<ng-template #defaultContent>
<p>Default content goes here.</p>
</ng-template>
</div>
- Use the
ng-template
tag for slot-based content projection:
// my-component.component.html
<div>
<ng-container *ngTemplateOutlet="contentTemplate || defaultContent"></ng-container>
<ng-template #defaultContent>
<p>Default content goes here.</p>
</ng-template>
</div>
- Use
@ContentChild
or@ContentChildren
decorators to access projected content programmatically in the component class.
// my-component.component.ts
import { ContentChild } from '@angular/core';
export class MyComponent {
@ContentChild('header') header: ElementRef;
}
Conclusion
Content projection is a powerful feature in Angular that allows you to pass content into a component from the parent component’s template. By mastering content projection, you can create more flexible and reusable components that can be customized with different content for various use cases. I hope this tutorial has provided you with a solid understanding of content projection in Angular and how to leverage it effectively in your applications.
👉 To try everything Brilliant has to offer for free for a full 30 days, visit https://brilliant.org/DecodedFrontend
You’ll also get 20% off an annual premium subscription.
Also there are some some bugs with angular–ssr and ng-content that the page will not render unless, the ng-content is whitin a @defer selector
thank you for keeping posting high quality content on Angular!
Gracias! Muy bien!
Fabulous material. Thanks.
Best! Best!!
Would you be able to access re-projected content programmatically? For example, can you access the projected content from the AppComponent in the ButtonComponent via ContentChildren or ContentChild?
The content shared in this video about content projection is a course in itself 🙂
Thank you for the detailed ng-content video. Always learn smth new from your videos. In current one it was – the re-projection tricks and using a directive for getting a reference to a template. Thanks.
Excelent explanation! thanks!
Thank you, your videos on Angular are the best.
Great job. You resolved my doubts about this topic!. It would be really great if you combine portals with content projection. For instance: single main toolbar that render different action buttons depending on the "page" component you've been routed to (every page has its own buttons which will be projected to the main toolbar). PS: using cdkPortalOutlet or so.
Thanks, Dmytro. As usual, your explanation is amazing!
Thanks for the well thought out material. I think that a clear understanding of content projection is essential for making dynamic reusable components.
You could consider making a course about angular cdk. thanks for video!
The conditional component projection is just what I was looking for today!! I am working on my custom components library! Thanks!!!
the only one thing that prevent ppl to understand ur explanation is they dont know english 😂
Content projection in Angular 18 seems a bit more sophisticated than that of React. Slots are a great pattern, I wish we could have a dedicated slot keyword for this sorta stuff. Using classes as identifier would be a mistake too.
Again amazing content! Thank you!
Amazing content… ng-content 🙂