Content Projection (ng-content)
5 questions found
What is content projection in Angular and what does ng-content do?
Beginner
Content projection lets a component accept and display content passed in by whatever uses it, similar to how a picture frame can hold any picture you place inside it. You add an ng-content tag in your component's template to mark exactly where that passed in content should appear.
@Component({
selector: 'app-card',
template: `
<div class="card">
<ng-content></ng-content>
</div>
`
})
export class CardComponent {}
// Used as:
// <app-card><p>This content gets projected inside</p></app-card>
Real-world example
A design team builds one reusable Card component, then uses it to display a product, a blog post, and a user profile, simply by passing different content inside it each time.
Common follow-ups: What happens if a component using ng-content is given no content at all?;Can you provide fallback content to show when nothing is projected?
Components & Templates;Standalone Components
How would you use multiple ng-content slots to project content into different specific locations within a component?
Intermediate
You add a select attribute to each ng-content tag, matching a specific CSS selector, letting content marked with a matching attribute or class be projected into that exact slot, rather than everything landing in the same single place.
@Component({
selector: 'app-layout',
template: `
<header><ng-content select="[header]"></ng-content></header>
<main><ng-content></ng-content></main>
`
})
export class LayoutComponent {}
// Used as:
// <app-layout>
// <nav header>Navigation</nav>
// <p>Main content here</p>
// </app-layout>
Real-world example
A shared layout component lets each page supply its own navigation content for the header slot and its own main content for the default slot, keeping the overall page structure consistent while the actual content varies per page.
Common follow-ups: What happens to content that does not match any select attribute on the ng-content tags?;Can you use a component selector, not just an attribute, as the select value?
Components & Templates;Standalone Components
How does ng-template work together with content projection to allow more flexible, conditional content?
Advanced
ng-template defines a piece of template content that is not rendered immediately by default, and a component can accept it as an input, deciding exactly when and how to render it, such as showing it conditionally or passing extra data into it, giving far more control than simple content projection alone.
@Component({
selector: 'app-panel',
template: `
@if (showDetails) {
<ng-container *ngTemplateOutlet="detailsTemplate"></ng-container>
}
`
})
export class PanelComponent {
@Input() detailsTemplate!: TemplateRef<any>;
showDetails = false;
}
Real-world example
A collapsible panel component only renders its detailed content template when expanded, using ng-template and ngTemplateOutlet to avoid rendering that content at all until the user actually needs to see it.
Common follow-ups: How does passing context data into an ng-template work when rendering it with ngTemplateOutlet?;What is the difference between ng-template and simply using ng-content?
Directives;Performance & Lazy Loading
How would you check whether any content was actually projected into a component using ng-content?
Intermediate
You can use the ContentChild decorator to get a reference to projected content, and check whether it exists after the view has initialized, letting you conditionally render fallback content or adjust your component's layout depending on whether real content was actually provided.
@Component({
selector: 'app-card',
template: `
<ng-content></ng-content>
@if (!hasContent) {
<p>No content provided</p>
}
`
})
export class CardComponent implements AfterContentInit {
@ContentChild('content') content: any;
hasContent = false;
ngAfterContentInit() { this.hasContent = !!this.content; }
}
Real-world example
A reusable card component shows a friendly placeholder message automatically whenever it is used without any content actually being provided inside it, checking for this using ContentChild after the view initializes.
Common follow-ups: Why must this check happen inside ngAfterContentInit rather than earlier lifecycle hooks?;What is the difference between ContentChild and ViewChild?
Lifecycle Hooks;Template Reference Variables & ViewChild
What is a simple real world example of when content projection is useful?
Beginner
A reusable alert box component can use content projection to display any message passed into it, whether that message is plain text, a link, or even another small component, without the alert box itself needing to know exactly what kind of content it will ever display.
@Component({
selector: 'app-alert',
template: `
<div class="alert">
<ng-content></ng-content>
</div>
`
})
export class AlertComponent {}
// Used differently in different places:
// <app-alert>Simple text message</app-alert>
// <app-alert><a href="/help">Need help? Click here</a></app-alert>
Real-world example
A website reuses the same AlertComponent to show a simple error message on one page and a message with a clickable link on another, thanks to content projection letting each usage supply completely different content.
Common follow-ups: How is content projection different from simply passing a string as a regular input?;Can content projection be combined with conditional rendering, like the new at if syntax?
Components & Templates;New Control Flow Syntax (@if
@for & @switch)