What Is the HTML <template> Element?
The HTML <template> element is a built-in mechanism for holding client-side content that you don't want to render immediately when the page loads. Its contents are stored as inert, reusable markup—not displayed, not executed, and not affecting the main document until you explicitly activate them with JavaScript.
<template id="my-template">
<div class="card">
<h2>Title</h2>
<p>Some description</p>
</div>
</template>
Unlike regular HTML placed directly in the document, the content inside a <template> is not rendered by the browser. Images are not fetched, styles don't apply globally, and scripts don't execute until the template is cloned and inserted into the live DOM.
Why the Template Element Matters
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Before templates became standard, developers often resorted to hidden <div> elements or <script type="text/template"> hacks to store reusable markup. These approaches had significant drawbacks:
- Premature resource loading: Hidden images or iframes still triggered network requests, wasting bandwidth.
- Script execution risks: JavaScript inside hidden elements could run unexpectedly.
- CSS pollution: Styles in hidden containers could interfere with the rest of the page, or be affected by global selectors.
- Clean separation: The
<template>element keeps content truly inert until you decide to stamp it out, offering a clear separation between definition and usage.
The template element solves these problems natively, making it a cornerstone for building efficient, reusable UI components, especially when combined with Web Components and dynamic list rendering.
How to Use the Template Element
1. Defining a Template
Place a <template> element anywhere inside the <body> (or <head>, though the body is more common for structural content). Always assign a unique id so you can easily reference it from JavaScript.
<template id="user-template">
<style>
.user-card { border: 1px solid #ccc; padding: 10px; margin: 5px; }
</style>
<div class="user-card">
<img src="" alt="user avatar" class="avatar">
<span class="name"></span>
</div>
</template>
The <style> block inside the template is also inert—it won't leak into the global document scope until after the template is stamped into the DOM.
2. Activating Template Content
To use the template, you must clone its content and insert the copy into the document. The template.content property returns a DocumentFragment that holds the template's internal nodes. Use cloneNode(true) to create a deep copy.
// Get the template element by its ID
const template = document.getElementById('user-template');
// Clone the content (true for deep clone)
const clone = template.content.cloneNode(true);
// Modify the clone before inserting
clone.querySelector('.name').textContent = 'Jane Doe';
clone.querySelector('.avatar').src = 'jane.jpg';
// Append to the live DOM
document.body.appendChild(clone);
Important: Always clone the fragment. If you try to directly insert template.content itself, the original fragment is moved, not copied. After one insertion, the template becomes empty and unusable for subsequent clones.
3. Populating Templates Dynamically
Create a helper function that clones the template, populates the necessary elements with data, and returns the completed fragment. This pattern is ideal for rendering lists or repeated UI blocks.
function createUserCard(name, avatarUrl) {
const template = document.getElementById('user-template');
const clone = template.content.cloneNode(true);
clone.querySelector('.name').textContent = name;
clone.querySelector('.avatar').src = avatarUrl;
return clone; // returns a DocumentFragment ready for insertion
}
const users = [
{ name: 'Alice', avatar: 'alice.jpg' },
{ name: 'Bob', avatar: 'bob.jpg' }
];
const container = document.getElementById('user-list');
users.forEach(user => {
container.appendChild(createUserCard(user.name, user.avatar));
});
4. Using Templates with Web Components
The <template> element is a natural fit for Web Components. You can define the component's shadow DOM structure inside a template, then clone it into the shadow root during component initialization.
// Define a custom element that uses a template
class UserCard extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
// Clone the template content
const template = document.getElementById('user-template');
const clone = template.content.cloneNode(true);
shadow.appendChild(clone);
// Populate from attributes
const name = this.getAttribute('name');
const avatar = this.getAttribute('avatar');
if (name) shadow.querySelector('.name').textContent = name;
if (avatar) shadow.querySelector('.avatar').src = avatar;
}
}
customElements.define('user-card', UserCard);
Now you can use <user-card name="Alice" avatar="alice.jpg"></user-card> directly in your HTML. The template's structure remains encapsulated within the shadow DOM, isolated from external styles.
Best Practices
- Always clone before insertion. Use
template.content.cloneNode(true)to obtain a fresh copy. Never move the original.contentfragment directly, as it destroys the template's reusability. - Keep templates inert. Avoid placing executable scripts directly inside
<template>that you expect to run upon cloning. Instead, attach event listeners and perform logic after cloning in JavaScript. - Use descriptive IDs. Give each
<template>a meaningfulid(likeuser-card-template) to simplify JavaScript selection and improve code readability. - Combine with
<slot>for flexibility. Inside a template meant for a web component, use<slot>elements to enable light DOM projection, making the component more versatile and customizable. - Do not style the
<template>tag itself. The<template>element is invisible and should not be targeted by CSS. Place all styling rules inside the template's content, where they will be scoped after stamping. - Use for repeated, dynamic UI patterns. Templates excel when you need to render lists, modals, tooltips, notifications, or any block that appears multiple times or after user interaction.
- Keep template content declarative. Templates should define structure and presentation, not behavior. Add interactivity (click handlers, data bindings) in JavaScript after cloning.
Conclusion
The HTML <template> element is a powerful, standards-based tool for modern web development. It allows you to define inert, reusable chunks of HTML that remain invisible and non-functional until you deliberately clone and insert them into the document. By leveraging templates, you avoid premature resource loading, prevent accidental script execution, and keep your global DOM clean. When combined with Web Components and dynamic stamping patterns, the template element helps you build efficient, maintainable, and high-performance user interfaces with a clear separation between structure and logic.