Customizable Ng-Content Elements

Let’s learn about the `ng-content` directive and how to customize it.

There are a few Angular core directives that we learned about recently, like NgIf, NgClass, and others. In this lesson, we’ll learn one more called ng-content. It’s a rather standard and commonly used directive, although we’ll learn it from scratch in this lesson. Most importantly, we’ll learn how to customize it using our attribute directives.

The ng-content directive

Creating highly reusable components often relates to a technique called content projection. Content projection is a pattern in component design that allows us to insert content generated from another component.

Let’s elaborate on the concept using some familiar examples. We’ll begin by asssuming that in the application codebase, we have many templates like this:

<button (click)="save()">
	Submit
	<fa-icon [icon]="faCheck"></fa-icon>
</button>

In the application, there’s a pattern to how buttons look. They often have their title and icon next to them. For this example, we might use “Font Awesome” icons.

It’s important to know that there’s nothing technically wrong with the code itself. However, duplications begin to appear if we have plenty of snippets like these in the codebase.

Most likely, the buttons will share the same style. They need to have a common button or button-primary class. They may need to apply a common directive, such as app-button or something similar. In the end, we may have a complicated snippet that duplicates, like this:

<button app-button class="button button-primary" (click)="save()">
	Submit
	<fa-icon [icon]="faCheck"></fa-icon>
</button>

The only thing that really changes when we use this template is the button’s title, which will look like this:

Submit

The icon can change as well, like this:

<fa-icon [icon]="faCheck"></fa-icon>

Ideally, we don’t want to add buttons like this repeatedly. Every time we need to add such a button, we just need to specify those two properties.

In a scenario like this, the content projection technique can definitely help us! For example, we could use the ng-content directive to project those two elements and leave everything else as part of the reusable component.

What if we were to use the reuasable button component, like this:

<app-button (click)="save()">
	Submit
	<fa-icon [icon]="faCheck"></fa-icon>
</app-button>

This looks much better! Now, let’s see how to implement this using the ng-content technique.

Angular treats the ng-content element placed in the component’s template as a kind of placeholder. It’s not rendered in the DOM. Instead, it gathers all the content passed inside the component’s tag and renders it in the place of ng-content.

Get hands-on with 1400+ tech skills courses.