Content Projection — ng-content, ng-template
Content projection lets you create flexible, reusable components that accept external content.
Content projection is a pattern where you insert external content INTO a component from outside. The component defines the structure (the "box"), and the parent decides what goes inside.
"Content projection = dabbey mein daalna — box ready hai, andar kya daalna tum decide karo."
Think of it like a gift box — the box is ready, but you decide what gift goes inside. Angular provides three tools for this:
- ng-content — For projecting HTML content into component slots
- ng-template — For defining reusable template blocks
- ng-container — For grouping elements without adding extra DOM nodes
ng-content creates a "slot" where parent content gets inserted:
// card.component.ts — template\n<div class="card">\n <ng-content></ng-content> <!-- Content appears here -->\n</div>\n\n// parent template\n<app-card>\n <h2>My Card Title</h2>\n <p>This content goes inside the card!</p>\n</app-card>
Whatever you write between the component tags is projected into the ng-content slot.
"ng-content = jhaadi pe hook — kuch bhi laga do." The component doesn't care what content goes in — it just provides the structure.
What if you need multiple projection slots? Use the select attribute:
// card.component.html\n<div class="card">\n <div class="header">\n <ng-content select="[card-header]"></ng-content>\n </div>\n <div class="body">\n <ng-content select="[card-body]"></ng-content>\n </div>\n <div class="footer">\n <ng-content select="[card-footer]"></ng-content>\n </div>\n</div>\n\n// Using the card\n<app-card>\n <div card-header>Title</div>\n <div card-body>Main content here</div>\n <div card-footer>Footer actions</div>\n</app-card>
The select attribute can use any CSS selector — attribute selectors [name] are most common.
"Multiple hooks = alag alag jagah alag cheezein laga sakte ho."
ng-template defines a template block that is NOT rendered by default. It only renders when explicitly referenced.
<ng-template #greeting>\n <h1>Hello, Hyderabad!</h1>\n <p>Welcome to the Angular course.</p>\n</ng-template>\n\n<!-- Render it using @if or *ngTemplateOutlet -->\n@if (showGreeting) {\n <ng-container *ngTemplateOutlet="greeting"></ng-container>\n}
"ng-template = recipe book mein recipe — tab tak cook nahi hoga jab tak use na karo." It's a recipe, not a cooked meal.
Use cases:
- Conditionally rendered content
- Reusable template fragments used in multiple places
- Template inputs to customize component rendering
ng-container is an invisible wrapper — it groups elements WITHOUT adding any extra DOM element.
<!-- BAD: adds unnecessary div -->\n<div *ngIf="isLoggedIn">\n <h2>Welcome back!</h2>\n <p>You have 3 notifications.</p>\n</div>\n\n<!-- GOOD: no extra DOM element -->\n<ng-container *ngIf="isLoggedIn">\n <h2>Welcome back!</h2>\n <p>You have 3 notifications.</p>\n</ng-container>
"ng-container = invisible box — andar ka stuff dikhta hai, box nahi."
This is especially important for CSS layouts. An extra div can break flexbox, grid, or other layout systems. Always use ng-container when you need a grouping element for structural directives.
Key Takeaways
- ✅ Content projection lets components accept external content — the "box" strategy.
- ✅ ng-content creates projection slots; single by default, multiple with select attribute.
- ✅ ng-template defines template blocks that are not rendered until explicitly used.
- ✅ ng-container groups elements without adding extra DOM nodes.
- ✅ Use select with attribute selectors (like [slot-name]) for multi-slot projection.
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login