Skip to Content
Course content

209: HTML Templates and Slots

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've noticed a lot of developers treating the <template> tag as if it's just a <div> with display: none. It seems like a harmless assumption—after all, the content doesn't show up on the page—but that misunderstanding will lead you straight into a wall when you try to actually manipulate the DOM.

Templates aren't just invisible divs

If you put a script tag or an image inside a hidden <div>, the browser still processes it. The image starts downloading, and the script executes the moment the DOM parses it. That's a performance killer if you're planning to create fifty instances of a complex UI component.

<!-- This is NOT a template. The image loads immediately! -->
<div style="display: none;" id="user-card-hidden">
  <img src="heavy-profile-pic.jpg">
  <p>User Profile</p>
</div>

Now, look at the <template> tag. The browser sees this and says, "I'll remember this for later, but I'm not touching it yet." The contents are stored in a DocumentFragment. Nothing inside is rendered, no network requests are fired for images, and no scripts run until you explicitly tell JavaScript to clone it into the active DOM.

Cloning the blueprint into reality

Since the template is inert, you can't just "show" it. You have to clone it. I usually recommend using cloneNode(true) to ensure you get all the nested children. I've found this to be far cleaner than building long, ugly strings of HTML inside your JS files, which is a nightmare to maintain and a security risk if you aren't careful with escaping.

<template id="product-row">
  <li class="product-item">
    <span class="name"></span>
    <span class="price"></span>
  </li>
</template>

<script>
  const template = document.querySelector('#product-row');
  const list = document.querySelector('#product-list');

  const products = [
    { name: 'Mechanical Keyboard', price: '$120' },
    { name: 'Gaming Mouse', price: '$60' }
  ];

  products.forEach(prod > {
    // We clone the content, not the template tag itself
    const clone = template.content.cloneNode(true);
    
    clone.querySelector('.name').textContent = prod.name;
    clone.querySelector('.price').textContent = prod.price;
    
    list.appendChild(clone);
  });
</script>

Slots are portals, not containers

Once you move into Web Components (Custom Elements), you'll encounter <slot>. A common mistake is thinking that the slot "contains" the content. It doesn't. A slot is a placeholder—a hole in your component's internal structure (the Shadow DOM) that lets external HTML "shine through."

Think of it like a picture frame. The frame is your Web Component, and the slot is the hole where the photo goes. The photo exists in the main document (the Light DOM), but it appears inside the frame.

// Inside your Custom Element's shadow root:
this.shadowRoot.innerHTML = `
  <div class="card-wrapper">
    <header>User Card</header>
    <div class="content-area">
      <slot>Default content if nothing is provided</slot>
    </div>
  </div>
`;

If you use this component like <user-card>Hello World</user-card>, the text "Hello World" is projected exactly where that <slot> tag is. You get the encapsulation of a component with the flexibility of custom content.




📋 Practical Task

Build a Dynamic Notification Toast System

Create a system that displays notification toasts using an HTML <template> and a custom Web Component with a <slot>.

  • The Template: Create a <template> in your HTML that contains the structure for a toast (e.g., a div with a class of "toast" and a close button).
  • The Web Component: Define a custom element called <notification-toast>. In its Shadow DOM, include a <slot> where the actual message will be projected.
  • The Logic: Write a JavaScript function showNotification(message) that:
    1. Clones the toast template.
    2. Creates an instance of your <notification-toast> component.
    3. Sets the innerHTML of the component to the provided message (which will fill the slot).
    4. Appends the component to the cloned toast, and the toast to the body.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.