Named Slots
This lesson explains named slots in Web Components and how to project content into specific regions such as headers, bodies, footers, and actions inside encapsulated custom elements.
What Are Named Slots?
Named slots let a Web Component define multiple content regions.
Consumers assign markup to a specific slot using the
slot attribute, and the browser projects that content
into the matching <slot name="..."> inside the
component.
They are ideal for layout components such as cards, dialogs, panels,
and page shells where different kinds of content belong in
different places.
| Concept | Description |
| Named Slot | <slot name="title"> |
| Slot Assignment | slot="title" on child content |
| Default Slot | <slot> for unmatched content |
| Fallback Content | Default markup inside a slot element |
| Main Benefit | Structured, composable component layouts |
| Works With | Shadow DOM and light DOM composition |
Basic Named Slots Example
class AppCard extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<article class="card">
<header>
<slot name="title"></slot>
</header>
<div class="body">
<slot></slot>
</div>
<footer>
<slot name="footer"></slot>
</footer>
</article>
`;
}
}
customElements.define("app-card", AppCard);
<app-card>
<h2 slot="title">Billing</h2>
<p>Your plan renews tomorrow.</p>
<button slot="footer" type="button">Manage Plan</button>
</app-card>
The title, body, and footer each go to a different slot region
inside the card layout.
How Named Slots Work
| Step | What Happens |
| 1. Component defines slot names | <slot name="title">, <slot name="footer"> |
| 2. Consumer assigns content | slot="title" on light DOM child |
| 3. Browser matches names | Content is projected to the correct region |
| 4. Unmatched content | Falls into the default <slot> |
| 5. Empty named slot | Shows fallback content if provided |
Default Slot vs Named Slots
<content-panel>
<h2 slot="title">Notifications</h2>
<p>You have 3 unread messages.</p>
<p>Your password was changed yesterday.</p>
<button slot="actions" type="button">View All</button>
</content-panel>
this.innerHTML = `
<section>
<header><slot name="title"></slot></header>
<div class="content"><slot></slot></div>
<footer><slot name="actions"></slot></footer>
</section>
`;
Use named slots for specific regions and the default slot for
general content that does not target a named area.
Named Slots in Shadow DOM
class DialogBox extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
this.shadowRoot.innerHTML = `
<style>
.dialog {
border: 1px solid #cbd5e1;
border-radius: 0.75rem;
padding: 1rem;
}
</style>
<section class="dialog" role="dialog">
<header>
<slot name="title">Dialog</slot>
</header>
<div><slot></slot></div>
<footer>
<slot name="actions"></slot>
</footer>
</section>
`;
}
}
<dialog-box>
<h2 slot="title">Delete Project</h2>
<p>This action cannot be undone.</p>
<button slot="actions" type="button">Delete</button>
</dialog-box>
Named slots are commonly used inside Shadow DOM to create
encapsulated layouts with flexible external content.
Fallback Content in Named Slots
this.shadowRoot.innerHTML = `
<article>
<header>
<slot name="title">Untitled Section</slot>
</header>
<div>
<slot>No content provided.</slot>
</div>
<footer>
<slot name="footer">
<button type="button">Continue</button>
</slot>
</footer>
</article>
`;
Each named slot can provide its own fallback content. If the
consumer does not supply content for that slot, the fallback
appears instead.
Multiple Elements in One Named Slot
<toolbar-panel>
<button slot="actions" type="button">Edit</button>
<button slot="actions" type="button">Share</button>
<button slot="actions" type="button">Delete</button>
</toolbar-panel>
More than one element can target the same named slot. They are
projected in document order inside that slot region.
Common Named Slot Layout Patterns
| Component | Common Slot Names |
| Card | title, default, footer |
| Dialog | title, default, actions |
| Page Layout | header, sidebar, default, footer |
| List Item | icon, default, meta |
| Media Card | media, title, default, cta |
Styling Named Slot Content
this.shadowRoot.innerHTML = `
<style>
::slotted([slot="title"]) {
margin: 0;
font-size: 1.25rem;
}
::slotted([slot="footer"]) {
margin-top: 1rem;
}
</style>
<article>
<header><slot name="title"></slot></header>
<div><slot></slot></div>
<footer><slot name="footer"></slot></footer>
</article>
`;
Inside Shadow DOM, use ::slotted() to style projected
content assigned to named slots.
Reacting to Named Slot Changes
this.shadowRoot.querySelectorAll("slot").forEach((slot) => {
slot.addEventListener("slotchange", () => {
const isEmpty =
slot.assignedElements().length === 0;
slot.parentElement.classList.toggle(
"is-empty",
isEmpty
);
});
});
Listen for slotchange on each named slot when layout
or empty states depend on whether content was provided.
When to Use Named Slots vs Default Slot
| Slot Type | Use When | Example |
| Named slot | Content belongs in a specific region | slot="title" |
| Default slot | General body content with no target name | <p>...</p> |
| Multiple named slots | Structured layout components | Card, dialog, page shell |
When to Use Named Slots
- Your component has multiple distinct content regions.
- You are building cards, dialogs, panels, or layouts.
- Consumers should control title, body, and actions separately.
- You want composable APIs instead of many string props.
- Different slot regions need separate fallback content.
- You need structured design system components.
Common Named Slot Use Cases
- Card headers, bodies, and footers.
- Dialog titles, content areas, and action buttons.
- Page layouts with header, sidebar, and footer regions.
- List items with icon, label, and metadata slots.
- Media components with image, title, and CTA slots.
- Form sections with label, input, and help text slots.
Named Slots Best Practices
- Use clear, predictable slot names such as
title and footer. - Document all supported slot names in component docs.
- Provide meaningful fallback content where helpful.
- Keep slot names short and consistent across your design system.
- Use the default slot for general content without a specific region.
- Style named slot content with
::slotted() in Shadow DOM. - Handle empty named slots with
slotchange when needed.
Common Named Slot Mistakes
- Misspelling slot names between component and consumer markup.
- Using too many named slots and making the API confusing.
- Assuming slot names are case-insensitive when they are not.
- Putting all content in named slots when the default slot is enough.
- Not providing fallback content for optional regions.
- Trying to style slotted content with normal descendant selectors in Shadow DOM.
- Not documenting which elements belong in each slot.
Key Takeaways
- Named slots let consumers target specific content regions.
- Use
slot="name" on content and <slot name="name"> in the component. - The default slot catches unmatched content.
- Named slots are ideal for cards, dialogs, and layout shells.
- Good slot naming makes components composable and easy to reuse.
Pro Tip
Name slots after layout regions, not implementation details. Names
like title, actions, and
footer are easier for consumers to understand than
internal names like region-a.