Render Markup Lazily or Group Without a Wrapper
ng-template & ng-container
The `<ng-template>` element is a chunk of markup you instantiate later, and `<ng-container>` groups children without adding a real DOM element.
What you'll learn
- Define an `<ng-template>` and render it on demand
- Use `<ng-container>` to avoid wrapper divs
- Accept an `<ng-template>` as a TemplateRef input
<ng-template> and <ng-container> are two special elements Angular
provides for shaping templates without disturbing the rendered DOM.
ng-container — Group Without a Wrapper
Sometimes you want to apply structural logic without adding a <div>
that breaks your layout. <ng-container> is invisible at runtime:
@if (user(); as u) {
<ng-container>
<h2>{{ u.name }}</h2>
<p>{{ u.bio }}</p>
</ng-container>
} The two children render side by side as siblings — no wrapper element appears in the DOM.
ng-template — Markup You Decide When to Render
<ng-template> defines markup that is not rendered immediately.
You can render it later by reference:
<ng-template #greeting let-name="name">
<p>Hello {{ name }}!</p>
</ng-template>
<ng-container *ngTemplateOutlet="greeting; context: { name: 'Ada' }">
</ng-container> The let-name syntax declares a template input variable, fed by the
context object.
Accepting a Template as an Input
A reusable component can accept an <ng-template> from its parent and
render it as a slot. This is how libraries expose customizable lists,
tables, and modals:
import { Component, contentChild, TemplateRef } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
@Component({
selector: 'app-list',
standalone: true,
imports: [NgTemplateOutlet],
template: `
@for (item of items; track item.id) {
<ng-container
*ngTemplateOutlet="rowTpl(); context: { $implicit: item }">
</ng-container>
}
`,
})
export class ListComponent {
items = [{ id: 1, name: 'Ada' }, { id: 2, name: 'Grace' }];
rowTpl = contentChild.required(TemplateRef);
} The parent uses it like this:
<app-list>
<ng-template let-item>
<strong>{{ item.name }}</strong>
</ng-template>
</app-list> When to Use Which
- Need to group children but don’t want a
<div>?<ng-container>. - Need markup that renders zero, one, or many times later?
<ng-template>. - Need a reusable slot in a library component? Accept a
TemplateRef.