# HTML <template> and <slot>: Reusable Markup and Content Projection

Source: https://devdocs10.com/articles/html/html-templates  
By Murat Bo · Published 2026-10-13 · DevDocs10 (https://devdocs10.com)

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

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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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.

```html
<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:**

```html
<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.
