Angular 17 multi-slot content projection

Content projection, also called transclusion, is like passing a note in class – it’s a feature in Angular that lets you share content between different components. With Angular 17, there’s a fresh approach to handling situations where you need to pass a lot of content around, making it simpler to keep things clean and organised inside a component.

Prerequisites

With Angular 17, you can create multiple areas within a component’s template where content from other components can be inserted. This is done using the ng-content element, and you can specify which content goes into which area by using the select attribute. It’s like having different trays or slots where you can place specific types of content that you want to include in your component.

For example, if you have a component with the following template

<div>
<h2>Header Content</h2>
<ng-content select="[header]"></ng-content>
</div>
<div>
<h2>Body Content</h2>
<ng-content select="[body]"></ng-content>
</div>
<div>
<h2>Footer Content</h2>
<ng-content select="[footer]"></ng-content>
</div>

The ng-content elements with the select attribute [header], [body], and [footer] define three different slots for content projection.

Features of multi-slot Content Projection

In Angular 17, multiple content projection brings some cool features:

  • Flexible Content Placement: Multi-slot content projection allows you to define multiple slots within a component’s template, giving flexibility in placing different pieces of content at specific locations.
  • Customizable Layout: Each slot can be styled and laid out independently within the component’s template, allowing for customizable layouts based on the projected content.
  • Improved Reusability: Components with multi-slot content projection can be highly reusable as they provide slots for various types of content, making them versatile across different parts of an application.
  • Enhanced Component Composition: Multi-slot content projection enhances component composition by enabling the assembly of complex UIs from smaller, reusable components. Parent components can provide content for each slot, allowing for granular control over the layout and structure of the composed UI.
  • Support for Transclusion: Multi-slot content projection builds upon Angular’s transclusion feature, allowing you to project content into multiple named slots within a component’s template.

Steps to Implement multi-slot content projection

Follow below steps to create an Angular 17 application with multiple content projection:

Step 1: Generate a new Angular project

ng new multiple-content-projection

Step 2: Generate a component

ng generate component content-projector

Folder Structure:

Dependencies

  "dependencies": {
"@angular/animations": "^17.2.0",
"@angular/common": "^17.2.0",
"@angular/compiler": "^17.2.0",
"@angular/core": "^17.2.0",
"@angular/forms": "^17.2.0",
"@angular/platform-browser": "^17.2.0",
"@angular/platform-browser-dynamic": "^17.2.0",
"@angular/platform-server": "^17.2.0",
"@angular/router": "^17.2.0",
"@angular/ssr": "^17.2.3",
"express": "^4.18.2",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
}

Step 3: Update the following codes.

HTML
<!--content-projector.component.html-->

<div>
    <h2>Header Content</h2>
    <ng-content select="[header]"></ng-content>
</div>
<div>
    <h2>Body Content</h2>
    <ng-content select="[body]"></ng-content>
</div>
<div>
    <h2>Footer Content</h2>
    <ng-content select="[footer]"></ng-content>
</div>
HTML
<!--app.component.html-->

<app-content-projector>
    <div header>
        <h3>This is the header content</h3>
    </div>
    <div body>
        <p>This is the body content</p>
    </div>
    <div footer>
        <p>This is the footer content</p>
    </div>
</app-content-projector>

In the example above, the ContentProjectorComponent defines three slots for content projection: [header], [body], and [footer]. When using this component in app.component.html, you can provide the content for each slot by wrapping it with the corresponding CSS selector (<div header>, <div body>, and <div footer>).

Output:

Output