Detailed explanation
The HTML <template> element stores a fragment of markup for later use, usually as a reusable building block in a dynamic interface. In its ordinary use, the browser parses the markup but does not render it as part of the page. Scripts inside the stored content do not execute while it remains there, and its elements do not participate in the visible document’s layout. This makes templates useful for repeated structures such as table rows, product cards, and notification items without keeping a visible example on screen.
Under the hood, an HTMLTemplateElement exposes its stored markup through the .content property, which is a DocumentFragment. Those nodes are not ordinary child nodes of the <template> element, so use template.content.querySelector(...) to search the stored structure. Calling template.content.cloneNode(true) creates a deep copy, including nested elements. JavaScript can then populate that copy and insert it into a live container. Appending a DocumentFragment moves its children into the destination; the fragment itself does not become a wrapper element in the rendered DOM.
In the table-row example, document.getElementById('row').content.cloneNode(true) copies the stored <tr> and <td>. Before appending it, you could assign clone.querySelector('.name').textContent = user.name. Appending the clone to a <tbody> inserts a real table row while leaving the original template available for subsequent rows. By contrast, appending template.content directly moves the original nodes out of storage, leaving it empty. For templates containing custom elements, document.importNode(template.content, true) is a useful alternative because it clones using the destination document’s context.
Interviewers generally look for three distinctions: inert storage versus CSS-hidden live content, the template element versus its content fragment, and cloning versus moving nodes. A template provides structure, not automatic data binding, sanitisation, or application behaviour. Populate untrusted text with textContent, and attach event listeners after cloning or use delegation because cloneNode does not copy listeners registered with addEventListener. Also recognise the modern exception: a qualifying <template shadowrootmode="open"> or "closed" can declaratively create a shadow root during HTML parsing, without manual JavaScript cloning.
Key points to remember
- Ordinary templates hold parsed, inert markup that is not rendered until inserted into the live document.
- Access the stored nodes through template.content, a DocumentFragment.
- Use cloneNode(true) to copy the complete structure while preserving the original template.
- Appending a fragment inserts its children without adding a wrapper element.
- Templates support reusable structure, but do not provide automatic data binding or sanitisation.
Common mistakes candidates make
- Treating <template> like display: none; CSS-hidden elements remain live document content rather than inert template content.
- Appending template.content directly when repeated reuse is intended, which empties the stored fragment.
- Assuming cloning copies addEventListener handlers or makes interpolated HTML safe.
Likely follow-up questions
How is <template> different from a hidden <div>?
A hidden <div> remains in the live document, even though CSS prevents it from being displayed. An ordinary template stores its descendants in an inert content fragment, so embedded scripts do not run while stored there.
Why does cloneNode(true) need the true argument?
The true argument requests a deep clone, including all descendants. Without it, cloning the content fragment produces an empty fragment because its child nodes are not copied.
How should you handle events on repeated template instances?
Attach listeners to each cloned instance before or after inserting it. Alternatively, attach one delegated listener to a stable ancestor and identify the relevant instance from the event target.
Interview tip: Explain inert storage first, then walk through accessing .content, deep-cloning it, populating a field, and appending the fragment.
