packages/html-template/README.md
Safe HTML template literals for Remix. html-template automatically escapes interpolated values to prevent XSS while still supporting explicit trusted HTML insertion.
html.raw when you need unescaped HTML from trusted sourcesnpm i remix
import { html } from 'remix/html-template'
let userInput = '<script>alert("XSS")</script>'
let greeting = html`<h1>Hello ${userInput}!</h1>`
console.log(String(greeting))
// Output: <h1>Hello <script>alert("XSS")</script>!</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/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.
SafeHtml values can be nested without double-escaping:
import { html } from 'remix/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>
`
You can interpolate arrays of values, which will be flattened and joined:
import { html } from 'remix/html-template'
let items = ['Apple', 'Banana', 'Cherry']
let list = html`
<ul>
${items.map((item) => html`<li>${item}</li>`)}
</ul>
`
Use null or undefined to render nothing:
import { html } from 'remix/html-template'
let showError = false
let errorMessage = 'Something went wrong'
let page = html`<div>${showError ? html`<div class="error">${errorMessage}</div>` : null}</div>`
@remix-run/fetch-router - HTTP router that works great with html-templateSee LICENSE