All questions

Tagged Template HTML

Premium

Tagged Template HTML

A tagged template is a function that receives a template literal split into its static parts and its interpolated values — html`<p>${name}</p>` calls html(['<p>', '</p>'], name). That split is exactly what you need to build HTML safely: the static parts are trusted markup you wrote, but the ${…} values are (potentially) untrusted data, so you escape them before stitching everything together. This is the core of lit-html, htm, and every "html in JS without a framework" library.

Implement the html tag. Join the literal parts with the escaped values, parse the result into a DocumentFragment via a <template>, and return it — so an injected <script> becomes harmless text, not a live element.

Signature

function html(strings, ...values) {
  // returns a DocumentFragment
}

Examples

const name = 'Ada';
html`<p>Hello ${name}</p>`;           // <p>Hello Ada</p>

html`<div>${'<img src=x onerror=hack()>'}</div>`;
// the value is escaped -> <div>&lt;img …&gt;</div> (text, not an <img>)

Notes

  • Static vs interpolatedstrings (the literal parts) are trusted HTML; the values are untrusted and must be HTML-escaped. Escape only the values.
  • Escape the five&, <, >, ", ' → their entities. An array value is escaped element-wise and joined.
  • Assemble — interleave: strings[0] + escape(values[0]) + strings[1] + escape(values[1]) + ….
  • Parse — set the assembled string as a <template>'s innerHTML and return template.content (a DocumentFragment you can insert anywhere).

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium