The template Element Inert Content
Define HTML that is parsed but not rendered until activated.
The template Element Inert Content is a free HTML Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is the template Element?
The <template> element holds HTML that is parsed but not rendered:
- Content is in the DOM but not displayed
- Scripts inside don't execute
- Images don't load
- CSS doesn't apply
- It is 'inert' until cloned
Basic template Usage
Define a template and inspect its content:
<template id="card-template">
<div class="card">
<h2 class="card-title"></h2>
<p class="card-body"></p>
<a class="card-link">Learn more</a>
</div>
</template>
<script>
const tmpl = document.getElementById('card-template');
console.log(tmpl.content); // DocumentFragment
console.log(tmpl.content.querySelector('.card')); // The div node
// Not rendered on the page yet
</script>template.content
The .content property returns a DocumentFragment:
const template = document.querySelector('#card-template');
const fragment = template.content;
// fragment is a DocumentFragment — a lightweight DOM container
// It is not attached to the document
// Modifying fragment does NOT affect the original template
// You must clone it before using itCloning a Template
Use cloneNode(true) to create a copy of the template content:
const tmpl = document.getElementById('card-template');
const clone = tmpl.content.cloneNode(true); // true = deep clone
// Modify the clone:
clone.querySelector('.card-title').textContent = 'HTML5 Guide';
clone.querySelector('.card-body').textContent = 'Learn HTML5 from scratch.';
clone.querySelector('.card-link').href = '/html5';
// Add to the page:
document.getElementById('card-list').appendChild(clone);Rendering a List from Template
Stamp out multiple items from one template:
<ul id="users"></ul>
<template id="user-tmpl">
<li class="user">
<strong class="user-name"></strong>
<span class="user-role"></span>
</li>
</template>
<script>
const tmpl = document.getElementById('user-tmpl');
const list = document.getElementById('users');
const users = [
{ name: 'Alice', role: 'Admin' },
{ name: 'Bob', role: 'Editor' },
];
users.forEach(user => {
const clone = tmpl.content.cloneNode(true);
clone.querySelector('.user-name').textContent = user.name;
clone.querySelector('.user-role').textContent = user.role;
list.appendChild(clone);
});
</script>Why template Instead of innerHTML?
template is safer and more efficient than innerHTML:
// innerHTML approach (less safe):
container.innerHTML = `<div>${userProvidedContent}</div>`;
// Risk: XSS if userProvidedContent is not sanitized
// template approach (safer):
const clone = tmpl.content.cloneNode(true);
clone.querySelector('.name').textContent = userProvidedContent;
// textContent sets text only — HTML tags are not parsed
// No XSS risktemplate with Nested Data
Complex templates with nested structures:
<template id="post-tmpl">
<article>
<header>
<h2 class="title"></h2>
<time class="date" datetime=""></time>
</header>
<p class="excerpt"></p>
<a class="read-more">Read more</a>
</article>
</template>
<script>
function renderPost(post) {
const clone = document.getElementById('post-tmpl').content.cloneNode(true);
clone.querySelector('.title').textContent = post.title;
clone.querySelector('.date').textContent = post.date;
clone.querySelector('.date').dateTime = post.isoDate;
clone.querySelector('.excerpt').textContent = post.excerpt;
clone.querySelector('.read-more').href = post.url;
return clone;
}
</script>template Is Not Rendered
Verify template content is hidden from users:
<template id="hidden-tmpl">
<script>alert('This runs when cloned, not when defined');</script>
<img src="wont-load-yet.jpg" alt="Won't load until cloned">
</template>
<!-- The script and image are NOT activated until you clone and append the template -->
<!-- This makes templates safe for defining content without side effects -->template vs script type=text/html
Legacy pattern vs modern template:
<!-- Old pattern (script hack): -->
<script type="text/html" id="old-tmpl">
<div class="card">...</div>
</script>
<script>
const html = document.getElementById('old-tmpl').innerHTML;
container.innerHTML = html; // XSS risk!
</script>
<!-- Modern template: -->
<template id="card-tmpl">...</template>
<!-- Safer, semantic, no XSS risk -->template in Component Libraries
Template patterns in vanilla component libraries:
class UserCard extends HTMLElement {
connectedCallback() {
const tmpl = document.getElementById('user-card-tmpl').content.cloneNode(true);
tmpl.querySelector('.name').textContent = this.getAttribute('name');
this.appendChild(tmpl);
}
}Quick Check
What does cloneNode(true) do with a template's content property?
Recap: template Element
Template essentials:
- Inert HTML — parsed but not rendered
template.content— returns a DocumentFragmentcontent.cloneNode(true)— deep copy, ready to modify and append- Safer than innerHTML — no HTML injection via textContent
- Used in custom elements, repeated UI patterns, and Web Components
Frequently asked questions
Is the “The template Element Inert Content” lesson free?
Yes — the full text of “The template Element Inert Content” is free to read here on the web, and the HTML Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the HTML Academy course, upgrade to CoddyKit PRO.
What will I learn in “The template Element Inert Content”?
Define HTML that is parsed but not rendered until activated. You practise HTML Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start HTML Academy?
No prior experience is required. HTML Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “The template Element Inert Content” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this HTML Academy lesson?
Yes. Every HTML Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- The template Element Inert Content
- Cloning Templates with cloneNode
- Using template with JavaScript Rendering
- Templates vs innerHTML Security