Skip to content

Templates and Slots Overview

The <template> element holds HTML markup that is inert: its content is parsed by the browser but never rendered, has no side-effects (no scripts run, no images load, no styles apply) until you explicitly clone it. Use templateEl.content.cloneNode(true) to stamp instances into the live document. This is efficient because the browser parses the markup exactly once, no matter how many instances you create.

A <slot> inside a shadow tree is a projection point. Light-DOM children placed inside the custom element are rendered at the slot’s position without being moved in the DOM. Named slots let you target specific insertion points: a child with slot="header" lands in <slot name="header">, while children without a slot attribute fall into the default <slot>.

flowchart LR
  subgraph "Light DOM (author)"
    H["slot='header' child"]
    B["slot='body' child"]
    U["(unslotted child)"]
  end
  subgraph "Shadow Tree (element)"
    SH["<slot name='header'>"]
    SB["<slot name='body'>"]
    SD["<slot> (default)"]
  end
  H --> SH
  B --> SB
  U --> SD
Light DOM children projected into shadow tree slots

This module walks through everything you need to know about the <template> element and shadow DOM slots, from basic usage to dynamic slot change events.

LessonDescription
Templates and Slots OverviewIntroduction to the module, the template element, and slots
The Template ElementDeep dive into .content, cloneNode, and why templates are inert
Default and Named SlotsHow to use <slot> and <slot name="..."> to project content
Slot Fallback ContentProviding default markup inside a slot when no content is projected
The slotchange EventReacting dynamically when assigned nodes change
What happens to the content inside a `<template>` element before it is cloned?
What does a `<slot>` element inside a shadow tree do?
Which method stamps a reusable copy of a template's content?