HTML <template> and <slot>: Reusable Markup and Content Projection
HTML template and slot are two advanced HTML features that help you build reusable interface pieces without duplicating markup. template stores inert HTML that does not render immediately, while slot lets a web component accept and place content from outside its shadow DOM.
Quick answer: Use template when you want HTML that exists in the page but does not render until you use it, and use slot when you want a web component to receive and display custom child content. They solve different problems and often work together.
Difficulty: Intermediate
You'll understand this better if you know: basic HTML structure, how attributes work, and the idea that web components can encapsulate markup.
1. What Are <template> and <slot>?
The template element is a container for HTML that the browser parses but does not display or activate right away. The slot element is used inside a web component’s shadow DOM to decide where light DOM content should appear.
- template holds reusable markup.
- template content is inert, so images do not load and scripts do not run from inside it.
- slot creates an insertion point for outside content.
- slot can have fallback content if nothing is provided.
- They are part of modern HTML and web components.
These features are closely related because reusable UI patterns often use a template to define structure and slot to customize parts of that structure.
2. Why <template> and <slot> Matter
Without these elements, reusable UI often means repeating the same markup or building everything with JavaScript string manipulation. That becomes harder to maintain, easier to break, and more difficult to make accessible.
template helps you define markup once and clone it when needed. slot helps component authors expose a clean API for content like titles, buttons, icons, or descriptions while keeping structure and styling encapsulated.
They matter most when you are building:
- custom elements and design system components
- repeated cards, dialogs, menus, or empty states
- content that should be authored in HTML but inserted dynamically
- components that need a sensible fallback when no custom content is provided
3. Basic Syntax or Core Idea
The simplest way to think about them is:
- template = store markup, do not render it yet.
- slot = reserve a place for content passed into a component.
3.1 The basic <template> structure
The browser parses the contents, but they stay hidden until something copies them into the document.
<template id="card-template">
<article class="card">
<h2>Card title</h2>
<p>Card content goes here.</p>
</article>
</template>This markup is valid HTML, but it does not appear on the page by itself. The content becomes useful only when a script or framework clones it.
3.2 The basic <slot> structure
A slot lives inside a shadow DOM template and marks where light DOM content should be inserted.
<template id="profile-card-template">
<article class="profile-card">
<h2><slot>Unnamed person</slot></h2>
<p><slot name="bio">No bio provided.</slot></p>
</article>
</template>Here the unnamed slot receives default children, and the named slot receives elements with a matching slot attribute.
4. Step-by-Step Examples
4.1 Cloning a template for repeated cards
This example shows the core reason template exists: you can define markup once and reuse it multiple times without copying HTML by hand.
<template id="news-card-template">
<article class="news-card">
<h2 class="title"></h2>
<p class="summary"></p>
</article>
</template>
<div id="news-feed"></div>In a real page, a script would clone the template content, fill in the title and summary, and append it to the feed. The important HTML idea is that the template is invisible until cloned.
4.2 Using a named slot for customizable text
Named slots let component users decide exactly where special content should go.
<template id="alert-box-template">
<article class="alert-box">
<h2><slot name="title">Alert</slot></h2>
<p><slot>Something happened.</slot></p>
</article>
</template>
<my-alert>
<span slot="title">Server error</span>
Please try again in a few minutes.
</my-alert>The slot="title" content goes into the named slot, while the plain text goes into the default slot.
4.3 Providing fallback content
Fallback content appears only when no matching light DOM content is provided.
<template id="dialog-template">
<dialog open>
<h2><slot name="heading">Default heading</slot></h2>
<p><slot>Default dialog body.</slot></p>
</dialog>
</template>This fallback is helpful because your component can still render something sensible when the author forgets to supply content.
4.4 Grouping multiple slotted regions
Complex components often need more than one insertion point, such as an icon, heading, body, and actions.
<template id="panel-template">
<section class="panel">
<header class="panel-header">
<slot name="icon"></slot>
<h2><slot name="title">Panel</slot></h2>
</header>
<div class="panel-body">
<slot>Panel content</slot>
</div>
<footer class="panel-footer">
<slot name="actions"></slot>
</footer>
</section>
</template>Multiple slots make component APIs explicit, which is often better than forcing every piece of content into one generic area.
5. Practical Use Cases
- Reusable card layouts for product listings, articles, or dashboards.
- Modal dialogs that need a title, body, and actions area.
- Custom elements that accept user-provided heading or body content.
- Empty-state screens with optional icons and call-to-action buttons.
- Notification banners with customizable labels and messages.
- Content-rich widgets where plain attribute values are not enough.
6. Common Mistakes
Mistake 1: Expecting <template> content to render automatically
A common beginner mistake is placing visible page content inside a template and expecting the browser to show it immediately.
Problem: The browser parses the markup, but template content is inert and does not appear in the document until it is cloned or otherwise inserted.
<template>
<p>This will not appear on the page yet.</p>
</template>Fix: Put the content outside the template if you want it visible immediately, or clone the template content into the page when needed.
<p>This appears immediately.</p>
<template>
<p>This is stored for later reuse.</p>
</template>The corrected version works because visible content is outside the inert template.
Mistake 2: Using the wrong slot name
If the slot attribute on the light DOM content does not match the named slot, the content falls back to the default slot or disappears from the intended location.
Problem: A name mismatch means the browser cannot associate the content with the slot you expected.
<template>
<h2><slot name="title">Default title</slot></h2>
</template>
<my-card>
<span slot="heading">Wrong slot name</span>
</my-card>Fix: Make the names match exactly.
<template>
<h2><slot name="title">Default title</slot></h2>
</template>
<my-card>
<span slot="title">Correct slot name</span>
</my-card>The corrected version works because the browser can now place the content into the named slot.
Mistake 3: Putting slotted content in the wrong tree
Slot assignment only works for light DOM children of the custom element, not for arbitrary elements elsewhere on the page.
Problem: Content outside the custom element cannot be projected into its slot, so the component renders fallback content instead.
<my-alert></my-alert>
<p slot="title">This is outside the component.</p>Fix: Place the slotted element as a child of the custom element.
<my-alert>
<p slot="title">This is inside the component.</p>
</my-alert>The corrected version works because the slotted node is now in the right relationship to the component.
7. Best Practices
Use <template> for structure, not for hidden page content
If content should be available to users immediately, do not bury it inside a template. Reserve templates for reusable markup or inert fragments.
<template id="item-template">
<li class="item"></li>
</template>This keeps your document semantics clear and prevents confusion about what is visible versus reusable.
Keep slot names meaningful and minimal
Good slot names describe the role of the content, such as title, icon, or actions. Avoid making every slot a one-off name that only you can understand.
<slot name="actions"></slot>
<slot name="icon"></slot>Clear names make component usage more predictable and easier to document.
Always provide sensible fallback content
Fallback content protects your component from looking broken when authors forget to provide optional children.
<slot name="title">Untitled</slot>This improves resilience and accessibility because the component still has readable text.
8. Limitations and Edge Cases
- template content is inert, so it will not run scripts or behave like live document content until inserted.
- slot works with the composed tree in web components, so styling and DOM inspection may feel different from normal HTML.
- Only direct children of the custom element can be assigned to its slots.
- Named slots require exact string matches; case and spelling matter.
- Fallback content disappears as soon as assigned content exists, so do not rely on both being shown together.
- Slots are not a general-purpose layout system for regular HTML outside web components.
- Older browsers may require a polyfill or may not support the full web components model.
9. Practical Mini Project
Here is a small but complete example of a product feature card built with a template and slots. The card supports a title, subtitle, body text, and optional actions.
<template id="feature-card-template">
<article class="feature-card">
<header>
<h2><slot name="title">Untitled feature</slot></h2>
<p class="subtitle">
<slot name="subtitle">No subtitle provided.</slot>
</p>
</header>
<div class="body">
<slot>Feature details go here.</slot>
</div>
<footer class="actions">
<slot name="actions"></slot>
</footer>
</article>
</template>
<feature-card>
<span slot="title">Fast setup</span>
<span slot="subtitle">Start in minutes</span>
This card reuses the same internal structure while letting the page author customize the text.
<button slot="actions">Learn more</button>
</feature-card>This project demonstrates the full pattern: the template defines the reusable component layout, and slots expose specific regions for content authored outside the component.
10. Key Points
- template stores inert HTML that can be reused later.
- slot defines where light DOM content appears inside a web component.
- Named slots and fallback content make components flexible and robust.
- Slot assignment depends on exact names and correct DOM placement.
- These features are especially useful for web components and reusable UI patterns.
11. Practice Exercise
Create a reusable notification panel that supports a title slot, a default message slot, and an actions slot.
- Use a template to define the panel markup.
- Add a named slot for the title.
- Add fallback text for the message.
- Add a named slot for action buttons.
Expected output: A component-like HTML structure where the heading, body, and actions can be replaced by custom content.
Hint: Use one unnamed slot for the main message and named slots for the title and actions areas.
Solution:
<template id="notification-panel-template">
<section class="notification-panel">
<header>
<h2><slot name="title">Notification</slot></h2>
</header>
<div class="message">
<slot>No message provided.</slot>
</div>
<footer class="actions">
<slot name="actions"></slot>
</footer>
</section>
</template>This solution works because each section has a clear insertion point, and the fallback text ensures the component remains useful even when no content is provided.
12. Final Summary
template and slot solve two related but different problems. template lets you define reusable, inert HTML that you can copy into the document when needed. slot lets a web component expose locations where outside content can appear.
Together, they make component-based HTML more maintainable, more predictable, and easier to customize. If you are learning web components next, a good follow-up topic is the shadow DOM, because slots are most powerful when you understand how shadow trees and light DOM work together.
Once you can read and write templates and slots confidently, you can build cleaner custom elements, design system components, and reusable page sections without duplicating markup everywhere.