Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Content Projection

Single slot

Use <ng-content> to project content into another component. Example:

import { Component } from "@angular/core";

@Component({
  selector: "app-zippy-basic",
  template: `
    <h2>Single-slot content projection</h2>
    <ng-content></ng-content>
  `,
})
export class ZippyBasicComponent {}

users of this component can project their own content

<app-zippy-basic>
  <p>Is content projection cool?</p>
</app-zippy-basic>

Multi-slot

You can add multiple contents slots and use a CSS selector to determine which ng-content tag to project your content into.

import { Component } from "@angular/core";

@Component({
  selector: "app-zippy-multislot",
  template: `
    <h2>Multi-slot content projection</h2>

    Default:
    <ng-content></ng-content>

    Question:
    <ng-content select="[question]"></ng-content>
  `,
})
export class ZippyMultislotComponent {}

and in consumer of the component:

<app-zippy-multislot>
  <p question>Is content projection cool?</p>
  <p>Let's learn about content projection!</p>
</app-zippy-multislot>

Conditional content projection

If your component needs to conditionally render content, or render content multiple times, you should configure that component to accept an <ng-template> element that contains the content you want to conditionally render.

Using an <ng-content> element in these cases is not recommended, because when the consumer of a component supplies the content, that content is always initialized, even if the component does not define an <ng-content> element or if that <ng-content> element is inside of an ngIf statement.

You can use ngTemplateOutlet directive to render a given <ng-template> element.

Template component:

<div *ngIf="expanded" [id]="contentId">
  <ng-container [ngTemplateOutlet]="content.templateRef"></ng-container>
</div>

Content component:

<ng-template appExampleZippyContent>
  It depends on what you do with it.
</ng-template>

Logic Angular will use when it encouters the appExampleZippyContent. This tells Angular to instantiate a template reference.

@Directive({
  selector: "[appExampleZippyContent]",
})
export class ZippyContentDirective {
  constructor(public templateRef: TemplateRef<unknown>) {}
}