HTML <template> Tag
The <template> tag is used to store code fragments that can be cloned and used in the HTML document again and again. See examples.
The <template> tag holds HTML markup that you want to reuse, but not render when the page loads. The browser parses the markup to make sure it's valid, then keeps it aside as an inert blueprint. You clone that blueprint with JavaScript whenever you need a copy in the live page — a common pattern for stamping out repeated list items, table rows, or cards.
This page covers what makes template content inert, how to activate it with JavaScript (content, cloneNode, appendChild), and a practical loop that builds many elements from a single template.
The <template> tag is a new element in HTML5. It can be placed anywhere inside <head> or <body>, and may contain any content those elements allow.
Why template content is inert
Everything inside a <template> is parsed like regular HTML, but the browser treats it as inert until you activate it. That means:
- It is not rendered — nothing inside the template appears on the page.
<script>tags inside it do not run.<style>tags inside it are not applied.- External resources do not load —
<img>,<video>, and<audio>sources are not fetched, so a template with 100 images costs you no network requests until you use it. - Its nodes are not part of the main document tree. Calling
document.getElementById()orquerySelector()on the page will not find elements that live inside a template.
This inertness is the whole point: you can ship a chunk of markup with the page that stays cheap and side-effect-free until the moment you actually need it.
Syntax
The <template> tag comes in pairs. The content is written between the opening (<template>) and closing (</template>) tags.
Example of the HTML <template> tag:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<h1>This is a heading.</h1>
<p>
<q>If you tell the truth, you don't have to remember anything.</q>
― Mark Twain
</p>
<template>
<h2>This is a second heading.</h2>
<p>
“I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.”
― Marilyn Monroe
</p>
</template>
</body>
</html>If you open the example above, the second heading and the Marilyn Monroe quote are nowhere on the page — they sit inside the <template>, which is invisible and inert at load time. Nothing renders until JavaScript clones the content into the live document.
Activating a template with JavaScript
To use template content, you read it through the element's content property, clone it, and insert the clone into the page. Here's the canonical pattern, broken down below:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<template id="myTemplate">
<p>Template content</p>
</template>
<div id="normalContent">
<p>First paragraph</p>
</div>
<!-- JavaScript function clones the template and adds it to the document. -->
<button onclick="useTemplate();">Show content</button>
<script>
function useTemplate() {
const myTemplate = document.getElementById('myTemplate');
const normalContent = document.getElementById('normalContent');
const clonedTemplate = myTemplate.content.cloneNode(true);
normalContent.appendChild(clonedTemplate);
}
</script>
</body>
</html>When the button is clicked, the useTemplate() function runs. Here is what each line does:
myTemplate.contentreturns the template'sDocumentFragment— a lightweight, off-document container holding the template's child nodes. You never insert this fragment directly, because doing so would empty the original template; you clone it instead..cloneNode(true)makes a deep clone of the fragment. Thetrueargument means "clone this node and all its descendants". Withfalseyou would copy only the empty fragment and lose the<p>inside it, so for templates you almost always passtrue.normalContent.appendChild(clonedTemplate)inserts the cloned nodes into the live DOM, after the existing first paragraph. Because it's a copy, the template stays untouched and can be reused as many times as you like.
For more on these methods, see JavaScript HTML DOM.
Use case: building repeated content in a loop
The real strength of <template> shows when you need many similar elements. Instead of writing each row by hand or building markup with string concatenation, you keep one blueprint and clone it for each piece of data:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<ul id="fruitList"></ul>
<template id="itemTemplate">
<li class="fruit"></li>
</template>
<script>
const fruits = ['Apple', 'Banana', 'Cherry'];
const list = document.getElementById('fruitList');
const template = document.getElementById('itemTemplate');
fruits.forEach(function (fruit) {
// Clone the template for each fruit.
const clone = template.content.cloneNode(true);
// Fill in the clone before inserting it.
clone.querySelector('.fruit').textContent = fruit;
list.appendChild(clone);
});
</script>
</body>
</html>This produces three <li> items, one per fruit. The same approach scales to table rows, product cards, or any list driven by data — define the markup once, clone it in a loop, and fill in the dynamic parts before appending.
The <template> tag supports the Global Attributes.