Tip: This guide assumes you've already read the Essentials Guide. Read that first if you're new to Angular.
You often need to create components that act as containers for different types of content. For example, you may want to create a custom card component:
@Component({ selector: 'custom-card', template: '<div class="card-shadow"> <!-- card content goes here --> </div>',})export class CustomCard {/* ... */}
You can use the <ng-content>
element as a placeholder to mark where content should go:
@Component({ selector: 'custom-card', template: '<div class="card-shadow"> <ng-content></ng-content> </div>',})export class CustomCard {/* ... */}
Tip: <ng-content>
works similarly
to the native <slot>
element,
but with some Angular-specific functionality.
When you use a component with <ng-content>
, any children of the component host element are
rendered, or projected, at the location of that <ng-content>
:
// Component source@Component({ selector: 'custom-card', template: ` <div class="card-shadow"> <ng-content /> </div> `,})export class CustomCard {/* ... */}
<!-- Using the component --><custom-card> <p>This is the projected content</p></custom-card>
<!-- The rendered DOM --><custom-card> <div class="card-shadow"> <p>This is the projected content</p> </div></custom-card>
Angular refers to any children of a component passed this way as that component's content. This is distinct from the component's view, which refers to the elements defined in the component's template.
The <ng-content>
element is neither a component nor DOM element. Instead, it is a special
placeholder that tells Angular where to render content. Angular's compiler processes
all <ng-content>
elements at build-time. You cannot insert, remove, or modify <ng-content>
at
run time. You cannot add directives, styles, or arbitrary attributes to <ng-content>
.
You should not conditionally include <ng-content>
with @if
, @for
, or @switch
. Angular always
instantiates and creates DOM nodes for content rendered to a <ng-content>
placeholder, even if
that <ng-content>
placeholder is hidden. For conditional rendering of component content,
see Template fragments.
Multiple content placeholders
Angular supports projecting multiple different elements into different <ng-content>
placeholders
based on CSS selector. Expanding the card example from above, you could create two placeholders for
a card title and a card body by using the select
attribute:
<!-- Component template --><div class="card-shadow"> <ng-content select="card-title"></ng-content> <div class="card-divider"></div> <ng-content select="card-body"></ng-content></div>
<!-- Using the component --><custom-card> <card-title>Hello</card-title> <card-body>Welcome to the example</card-body></custom-card>
<!-- Rendered DOM --><custom-card> <div class="card-shadow"> <card-title>Hello</card-title> <div class="card-divider"></div> <card-body>Welcome to the example</card-body> </div></custom-card>
The <ng-content>
placeholder supports the same CSS selectors
as component selectors.
If you include one or more <ng-content>
placeholders with a select
attribute and
one <ng-content>
placeholder without a select
attribute, the latter captures all elements that
did not match a select
attribute:
<!-- Component template --><div class="card-shadow"> <ng-content select="card-title"></ng-content> <div class="card-divider"></div> <!-- capture anything except "card-title" --> <ng-content></ng-content></div>
<!-- Using the component --><custom-card> <card-title>Hello</card-title> <img src="..." /> <p>Welcome to the example</p></custom-card>
<!-- Rendered DOM --><custom-card> <div class="card-shadow"> <card-title>Hello</card-title> <div class="card-divider"></div> <img src="..." /> <p>Welcome to the example></p> </div></custom-card>
If a component does not include an <ng-content>
placeholder without a select
attribute, any
elements that don't match one of the component's placeholders do not render into the DOM.
Fallback content
Angular can show fallback content for a component's <ng-content>
placeholder if that component doesn't have any matching child content. You can specify fallback content by adding child content to the <ng-content>
element itself.
<!-- Component template --><div class="card-shadow"> <ng-content select="card-title">Default Title</ng-content> <div class="card-divider"></div> <ng-content select="card-body">Default Body</ng-content></div>
<!-- Using the component --><custom-card> <card-title>Hello</card-title> <!-- No card-body provided --></custom-card>
<!-- Rendered DOM --><custom-card> <div class="card-shadow"> Hello <div class="card-divider"></div> Default Body </div></custom-card>
Aliasing content for projection
Angular supports a special attribute, ngProjectAs
, that allows you to specify a CSS selector on
any element. Whenever an element with ngProjectAs
is checked against an <ng-content>
placeholder, Angular compares against the ngProjectAs
value instead of the element's identity:
<!-- Component template --><div class="card-shadow"> <ng-content select="card-title"></ng-content> <div class="card-divider"></div> <ng-content></ng-content></div>
<!-- Using the component --><custom-card> <h3 ngProjectAs="card-title">Hello</h3> <p>Welcome to the example</p></custom-card>
<!-- Rendered DOM --><custom-card> <div class="card-shadow"> <h3>Hello</h3> <div class="card-divider"></div> <p>Welcome to the example></p> </div></custom-card>
ngProjectAs
supports only static values and cannot be bound to dynamic expressions.