---
title: "Clone markup that scripts add from a · Agent Wranglers"
url: https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/template-element
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Clone markup that scripts add from a template element

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

For AI agents: [llms.txt](https://agentwranglers.se/llms.txt) is a short guide that sends you to the rules your problem needs, and [rules.json](https://agentwranglers.se/playbook/html-css/rules.json) holds every rule of this playbook as JSON.

- Level: Recommended
- Chapter: [HTML structure and reuse](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse)
- Rule: Keep every piece of markup that a script inserts in a `<template>` element in the page. Scripts clone it and fill in text, and never build HTML in strings.
- How: The browser keeps a template's contents inert, so nothing in it renders or runs until a script clones it. Markup then stays in HTML, where the markup linter and the unused-selector check can see it. Fill each clone with `textContent` and attributes, never `innerHTML`. Prove that with the attack in [Escape everything you show](https://agentwranglers.se/playbook/adversarial-testing/injection/cross-site-scripting). For the browser lock on HTML writes, see [Lock down risky DOM writes](https://agentwranglers.se/playbook/website/security/trusted-types).
- Check: A search of the scripts finds 0 string literals that contain an HTML tag and 0 assignments to `innerHTML` or `outerHTML`. Every `<template>` id that a script clones exists in a built page.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### HTML example

```html
<template id="basket-line-template">
  <li class="basket-line"><span class="basket-line-name" data-part="name"></span> <span class="basket-line-price" data-part="price"></span></li>
</template>
```

### JavaScript example

```js
const lineTemplate = document.getElementById('basket-line-template');

export function basketLine({ name, price }) {
  const line = lineTemplate.content.firstElementChild.cloneNode(true);
  line.querySelector('[data-part="name"]').textContent = name;
  line.querySelector('[data-part="price"]').textContent = price;
  return line;
}
```

### Python example

```python
# Build check: scripts hold no HTML strings and no innerHTML writes
import pathlib, re, sys
HTML_IN_STRING = re.compile(r"""['"`]\s*<[a-z][\w-]*[\s>/]""")
HTML_WRITE = re.compile(r"\.(innerHTML|outerHTML)\s*\+?=")
hits = [f"{p}:{n}" for p in pathlib.Path("src").rglob("*.js")
        for n, line in enumerate(p.read_text().splitlines(), 1)
        if HTML_IN_STRING.search(line) or HTML_WRITE.search(line)]
print("\n".join(f"FAIL {hit} builds markup in a script" for hit in hits))
sys.exit(1 if hits else 0)
```

## Sources

- [HTML Standard on the template element](https://html.spec.whatwg.org/multipage/scripting.html#the-template-element)

## Related rules

- [Escape everything you show](https://agentwranglers.se/playbook/adversarial-testing/injection/cross-site-scripting) in Security testing
- [Lock down risky DOM writes](https://agentwranglers.se/playbook/website/security/trusted-types) in Website

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/template-element">Agent Wranglers HTML and CSS playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Avoid wrapper elements that only hold a class](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/no-wrapper-divs)
- Next: [Name custom elements with the project prefix](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/custom-element-names)
- [HTML structure and reuse](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse)
