JSPM

@remix-run/html-template

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2313
  • Score
    100M100P100Q115546F
  • License MIT

HTML template tag with auto-escaping for JavaScript

Package Exports

  • @remix-run/html-template
  • @remix-run/html-template/package.json

Readme

html-template

Safe HTML template tag with auto-escaping for JavaScript.

html-template provides a tagged template literal for safely constructing HTML strings with automatic escaping of interpolated values to prevent XSS vulnerabilities.

Features

  • Automatic HTML escaping - All interpolated values are escaped by default
  • Explicit raw HTML - Use html.raw when you need unescaped HTML from trusted sources
  • Composable - SafeHtml values can be nested without double-escaping
  • Type-safe - Full TypeScript support with branded types
  • Zero dependencies - Lightweight and self-contained
  • Runtime agnostic - Works in Node.js, Bun, Deno, browsers, and edge runtimes

Installation

Install from npm:

npm install @remix-run/html-template

Usage

import { html } from '@remix-run/html-template'

let userInput = '<script>alert("XSS")</script>'
let greeting = html`<h1>Hello ${userInput}!</h1>`

console.log(String(greeting))
// Output: <h1>Hello &lt;script&gt;alert("XSS")&lt;/script&gt;!</h1>

By default, all interpolated values are automatically escaped to prevent XSS attacks.

If you have trusted HTML that should not be escaped, use html.raw:

import { html } from '@remix-run/html-template'

let trustedIcon = '<svg>...</svg>'
let button = html.raw`<button>${trustedIcon} Click me</button>`

console.log(String(button))
// => <button><svg>...</svg> Click me</button>

Warning: Only use html.raw with content you trust. Never use it with user input.

Composing HTML Fragments

SafeHtml values can be nested without double-escaping:

import { html } from '@remix-run/html-template'

let title = html`<h1>My Title</h1>`
let content = html`<p>Some content with ${userInput}</p>`

let page = html`
  <!doctype html>
  <html>
    <body>
      ${title} ${content}
    </body>
  </html>
`

Working with Arrays

You can interpolate arrays of values, which will be flattened and joined:

import { html } from '@remix-run/html-template'

let items = ['Apple', 'Banana', 'Cherry']
let list = html`
  <ul>
    ${items.map((item) => html`<li>${item}</li>`)}
  </ul>
`

Conditional Rendering

Use null or undefined to render nothing:

import { html } from '@remix-run/html-template'

let showError = false
let errorMessage = 'Something went wrong'
let page = html`<div>${showError ? html`<div class="error">${errorMessage}</div>` : null}</div>`

License

See LICENSE