Understanding the HTML `<template>` Tag: A Guide for Developers

Blog

Posted by Nuno Marques on 24 Feb 2025

Understanding the HTML `<template>` Tag: A Guide for Developers

Introduction

The <template> tag is an essential feature introduced in HTML5, designed to handle reusable content without immediately rendering it in the document. This tag enables developers to define inert DOM structures—elements that exist in the document but do not appear until explicitly activated. This behavior is particularly useful in modern web development, where dynamic content manipulation is key to building interactive applications.

The <template> tag is commonly used in JavaScript-powered applications for inserting and cloning content dynamically, improving performance, code maintainability, and user experience. In this article, we'll explore how it works, its practical applications, and best practices for its implementation.


How It Works

The <template> tag contains markup that is not immediately rendered when the page loads. Instead, it remains inactive until accessed and manipulated via JavaScript.

Key Features of <template>:

  • Hidden Until Activated: Content inside <template> is ignored by the browser until it's explicitly cloned and inserted.
  • Preserves Internal Structure: Unlike display: none, elements inside a <template> are not part of the rendered DOM.
  • Ideal for Dynamic Content: Used with JavaScript to generate UI components dynamically.

Example:

<template id="greeting-template">
    <p>Hello, <span class="name"></span>!</p>
</template>

Here, the paragraph inside the <template> will not appear on the page until it is manually inserted into the DOM.


Use Cases of <template>

1. Dynamic Content Injection

One of the most common use cases of <template> is dynamically injecting content into a webpage using JavaScript.

Example:

<template id="message-template">
    <div class="message">Welcome, <span class="username"></span>!</div>
</template>

<div id="container"></div>

<script>
    function showMessage(name) {
        const template = document.getElementById("message-template");
        const clone = template.content.cloneNode(true);
        clone.querySelector(".username").textContent = name;
        document.getElementById("container").appendChild(clone);
    }
    
    showMessage("Alice");
</script>

What’s happening?

  • The <template> is defined but remains hidden.
  • JavaScript clones its content and inserts it into the document.
  • The user’s name is dynamically updated before insertion.

2. Reusable UI Components

Templates are perfect for reusing small UI components without cluttering the HTML.

Example:

<template id="card-template">
    <div class="card">
        <h2 class="title"></h2>
        <p class="description"></p>
    </div>
</template>

<div id="card-container"></div>

<script>
    function createCard(title, description) {
        const template = document.getElementById("card-template");
        const clone = template.content.cloneNode(true);
        clone.querySelector(".title").textContent = title;
        clone.querySelector(".description").textContent = description;
        document.getElementById("card-container").appendChild(clone);
    }
    
    createCard("Card Title 1", "This is a description.");
    createCard("Card Title 2", "Another card description.");
</script>

In this example, the template acts as a blueprint for multiple UI cards, allowing easy duplication and modification.

3. Performance Enhancements

Since content inside <template> is not rendered immediately, it prevents unnecessary reflows and repaints, leading to better performance. This is especially useful for pages that require deferred content loading, such as:

  • Lazy-loaded elements
  • Expanding UI sections
  • Dynamic list rendering

Best Practices

To maximize the benefits of <template>, follow these best practices:

✅ Use JavaScript to Manage Templates

Instead of keeping numerous hidden elements in the DOM, use JavaScript to insert and remove content as needed.

✅ Clone and Append Templates Properly

Always use .content.cloneNode(true) to copy template contents before inserting them into the DOM.

❌ Avoid Using <template> for Static Content

If the content never changes dynamically, it's better to place it directly in the HTML to avoid unnecessary JavaScript overhead.

✅ Ensure Proper Data Binding

If using <template> for dynamic elements, ensure correct event delegation since cloned elements do not retain JavaScript event listeners.


Real-World Example

Here’s a complete example demonstrating how <template> can be used for dynamic to-do lists:

<template id="todo-template">
    <li class="todo-item">
        <span class="task"></span>
        <button class="remove">Remove</button>
    </li>
</template>

<ul id="todo-list"></ul>
<input type="text" id="task-input" placeholder="Enter a task">
<button onclick="addTask()">Add Task</button>

<script>
    function addTask() {
        const taskInput = document.getElementById("task-input");
        if (!taskInput.value) return;
        
        const template = document.getElementById("todo-template");
        const clone = template.content.cloneNode(true);
        clone.querySelector(".task").textContent = taskInput.value;
        
        clone.querySelector(".remove").addEventListener("click", function() {
            this.parentElement.remove();
        });
        
        document.getElementById("todo-list").appendChild(clone);
        taskInput.value = "";
    }
</script>

What This Code Does:

  • Adds new to-do list items dynamically using <template>.
  • Uses JavaScript to manage the list and handle interactions.
  • Improves efficiency by reducing the number of initially rendered elements.

Conclusion

The <template> tag is a powerful and efficient way to manage reusable and dynamic content in modern web applications. By leveraging inert templates, developers can improve performance, structure code more effectively, and create highly interactive UI components.

Further Reading:

By incorporating <template> into your workflow, you can streamline development and build more efficient, maintainable applications. Happy coding!