ng-content is used to display children in a template, ng-container is used as a non-rendered container to avoid having to add a span or a div, and ng-template allows you to group some content that is not rendered directly but can be used in other places of your template or your code.
ng-template
ng-template is a template element is used in Angular with structural directives and custom directives.
<div *ngIf="showTitle; else noTitle">
<h1>Home</h1>
</div>
<ng-template #noTitle>
<p>No title</p>
</ng-template>
ng-container
ng-container is a non-rendered container element that is used to group elements. It is used to avoid having to add a span or a div.
<ng-container *ngIf="showTitle;">
<h1>Home</h1>
</ng-container>
It is also useful when you want to use multiple structural directives on the same element.
<div *ngIf="details" *ngFor="let info of details">
{{ info.content }}
</div>
The above code will not work because you cannot use multiple structural directives on the same element. You can use ng-container to solve this problem.
<ng-container *ngIf="details">
<div *ngFor="let info of details">
{{ info.content }}
</div>
</ng-container>
ng-content
ng-content is used to insert content dynamically into a component.
<app-card>
<h1>Home</h1>
</app-card>
<div class="card">
<div class="card-body">
<ng-content></ng-content>
</div>
</div>
ng-content with select (insert the content in multiple places)
<app-card>
<h1 class="title">Title</h1>
<p class="content">Content</p>
</app-card>
<div class="card">
<div class="card-body">
<ng-content select=".title"></ng-content>
</div>
Text in-between
<div class="card-footer">
<ng-content select=".content"></ng-content>
</div>
</div>