Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Content Projection in Angular

What is Content Projection?

Content projection lets a parent component pass HTML content into a child component's template. The child uses <ng-content> as a slot where the projected content is rendered. It's Angular's equivalent of "slots" in Vue or "children" in React.

Single-Slot Projection

Single Slot
import { Component } from '@angular/core';

@Component({
    selector: 'app-card',
    standalone: true,
    template: `
        <div class="card">
            <div class="card-body">
                <ng-content />
            </div>
        </div>
    `,
    styles: [`.card { border: 1px solid #ddd; border-radius: 8px; padding: 16px; }`]
})
export class CardComponent {}
<!-- Parent template -->
<app-card>
    <h2>Card Title</h2>
    <p>This content is projected into the card.</p>
    <button>Action</button>
</app-card>

Multi-Slot Projection with select

Use the select attribute on <ng-content> to target specific elements by CSS selector.

Multi-Slot Projection
import { Component } from '@angular/core';

@Component({
    selector: 'app-panel',
    standalone: true,
    template: `
        <div class="panel">
            <div class="panel-header">
                <ng-content select="[panel-header]" />
            </div>
            <div class="panel-body">
                <ng-content select="[panel-body]" />
            </div>
            <div class="panel-footer">
                <ng-content select="[panel-footer]" />
            </div>
        </div>
    `
})
export class PanelComponent {}
<app-panel>
    <h2 panel-header>Panel Title</h2>
    <p panel-body>Main content goes here.</p>
    <button panel-footer>Close</button>
</app-panel>

ng-template and ng-container

ng-template & ng-container
<!-- ng-container: grouping without adding DOM elements -->
<ng-container>
    @if (isAdmin()) {
        <button>Admin Panel</button>
        <button>Settings</button>
    }
</ng-container>

<!-- ng-template: define a reusable template block -->
<ng-template #loadingTpl>
    <div class="spinner">Loading...</div>
</ng-template>

<ng-template #errorTpl let-msg="message">
    <div class="error">{{ msg }}</div>
</ng-template>

<!-- Use ngTemplateOutlet to render a template -->
@if (isLoading()) {
    <ng-container [ngTemplateOutlet]="loadingTpl" />
}

ContentChild — Accessing Projected Content

contentChild()
import { Component, contentChild, AfterContentInit } from '@angular/core';
import { TabComponent } from './tab.component';

@Component({
    selector: 'app-tabs',
    standalone: true,
    template: `
        <div class="tabs">
            <ng-content />
        </div>
    `
})
export class TabsComponent implements AfterContentInit {
    // Signal-based contentChild (Angular 17+)
    firstTab = contentChild(TabComponent);

    ngAfterContentInit() {
        // Projected content is available here
        console.log('First tab:', this.firstTab());
    }
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.