Skip to main content
Practice Problems

Content projection (ng-content) in Angular

What is Content Projection?

Content projection allows you to pass HTML content from a parent component into a child component's template. It's Angular's equivalent of React's children or Vue's slots.


Single-Slot Projection

typescript
// card.component.ts @Component({ selector: 'app-card', standalone: true, template: \` <div class="card"> <div class="card-body"> <ng-content></ng-content> </div> </div> \` }) export class CardComponent {}
html
<!-- Usage --> <app-card> <h2>Card Title</h2> <p>Any content can go here!</p> <button>Action</button> </app-card>

Multi-Slot Projection

Use select attribute to project content into specific slots:

typescript
@Component({ selector: 'app-dialog', template: \` <div class="dialog"> <header> <ng-content select="[dialog-header]"></ng-content> </header> <main> <ng-content select="[dialog-body]"></ng-content> </main> <footer> <ng-content select="[dialog-footer]"></ng-content> </footer> </div> \` }) export class DialogComponent {}
html
<app-dialog> <div dialog-header> <h2>Confirm Delete</h2> </div> <div dialog-body> <p>Are you sure you want to delete this item?</p> </div> <div dialog-footer> <button (click)="cancel()">Cancel</button> <button (click)="confirm()">Delete</button> </div> </app-dialog>

Select Options

html
<!-- By attribute --> <ng-content select="[header]"></ng-content> <!-- By CSS class --> <ng-content select=".footer"></ng-content> <!-- By element --> <ng-content select="h2"></ng-content> <!-- By component --> <ng-content select="app-icon"></ng-content> <!-- Default (unmatched content) --> <ng-content></ng-content>

Conditional Projection with ng-template

typescript
@Component({ selector: 'app-expandable', template: \` <div class="header" (click)="toggle()"> <ng-content select="[title]"></ng-content> </div> <div class="body" *ngIf="isOpen"> <ng-content select="[content]"></ng-content> </div> \` }) export class ExpandableComponent { isOpen = false; toggle() { this.isOpen = !this.isOpen; } }

ContentChild and ContentChildren

Access projected content programmatically:

typescript
@Component({ /* ... */ }) export class TabsComponent implements AfterContentInit { @ContentChildren(TabComponent) tabs!: QueryList<TabComponent>; ngAfterContentInit() { // Access projected tab components const activeTabs = this.tabs.filter(tab => tab.active); if (activeTabs.length === 0) { this.tabs.first.active = true; } } }
html
<app-tabs> <app-tab title="Home">Home content</app-tab> <app-tab title="Settings">Settings content</app-tab> <app-tab title="Profile" [active]="true">Profile content</app-tab> </app-tabs>

Important:

Content projection with <ng-content> lets you create flexible, reusable wrapper components (cards, dialogs, layouts). Use select for multi-slot projection. Use @ContentChildren to access projected components programmatically. It's Angular's version of React's children prop or Vue's slots.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems