@leafac/html
Radically Straightforward HTML
Videos
Installation
$ npm install @leafac/html
We recommend using @leafac/html along with the following tools:
Formatting: Prettier and the Visual Studio Code extension Prettier - Code formatter.
Syntax Highlighting: The Visual Studio Code extension es6-string-html.
Features, Usage, and Examples
Use tagged templates as an HTML template engine. For example:
import html from "@leafac/html";
console.log(html`<p>${"Leandro Facchinetti"}</p>`); // => <p>Leandro Facchinetti</p>
Safe by default. For example:
console.log(html`<p>${`<script>alert(1);</script>`}</p>`); // => <p><script>alert(1);</script></p>
Unsafely interpolate trusted HTML with $${...}
. For example:
console.log(html`<p>$${`<span>Leandro Facchinetti</span>`}</p>`); // => <p><span>Leandro Facchinetti</span></p>
Join interpolated arrays. For example:
console.log(html`<p>${["Leandro", " ", "Facchinetti"]}</p>`); // => <p>Leandro Facchinetti</p>
Array interpolation is safe by default; if you wish to unsafely interpolate an array of trusted HTML use $${[...]}
.
@leafac/html doesn’t encode HTML itself. It relies on entities, which is a mature solution and covers all the edge cases.
@leafac/html doesn’t format the output. If you need pretty HTML, you may pass the output of @leafac/html to Prettier.
@leafac/html generates strings. No virtual DOM in sight. For readability, the HTML
type is exported in TypeScript. For example:
import html, { HTML } from "@leafac/html";
const name: HTML = html`<p>Leandro Facchinetti</p>`;
console.log(name);
@leafac/html sanitizes (removes) invalid XML characters. It uses sanitize-xml-string. For example:
console.log(html`<p>A backspace is invalid in XML: ${`|\b|`}</p>`); // => <p>A backspace is invalid in XML: ||</p>
@leafac/html is fast. Rendering HTML tends to be one of the most expensive computations in a web server, so it must be fast. @leafac/html is more than one order of magnitude faster than ReactDOMServer.renderToStaticMarkup()
.
Related Projects
- https://npm.im/@leafac/sqlite: Radically Straightforward SQLite.
- https://npm.im/@leafac/css: Radically Straightforward CSS.
- https://npm.im/@leafac/javascript: Radically Straightforward Client-Side JavaScript.
Prior Art
-
https://npm.im/html-template-tag:
- Was a major inspiration for this. Its design is simple and great. In particular, I love (and stole) the idea of using
$${...}
to mark unsafe interpolation of trusted HTML. - Doesn’t encode arrays by default.
- Uses a bespoke encoding.
- Was a major inspiration for this. Its design is simple and great. In particular, I love (and stole) the idea of using
-
https://npm.im/common-tags:
- Doesn’t encode interpolated values by default.
- Uses the
safeHtml
tag, which isn’t recognized by Prettier or the Visual Studio Code extension es6-string-html extension.
-
https://npm.im/escape-html-template-tag:
- Less ergonomic API with
escapeHtml.safe()
andescapeHtml.join()
instead of the$${}
trick. - Uses a bespoke encoding.
- Less ergonomic API with
-
https://npm.im/lit-html, https://npm.im/nanohtml, https://npm.im/htm, and https://npm.im/viperhtml:
- Have the notion of virtual DOM instead of simple string concatenation.
Changelog
4.0.1 · 2023-02-21
- Now it’s possible to import @leafac/html in the browser, which is useful for client-side components, for example, date pickers.
- Made @leafac/html 3.5x faster by changing from he entities.
- Switched from custom test runner to Node.js’s test runner.
4.0.0 · 2022-12-02
- Reimplemented @leafac/html to improve performance. Measured a 2x speedup with respect to version 3.0.3.
Breaking Changes
-
Use default import instead of named import for
html
.Before:
import { html, HTML } from "@leafac/html";
After:
import html, { HTML } from "@leafac/html";
-
We no longer sanitize XML characters in the literal template or in unsafe substitutions (those using
$${...}
). This was one of the reasons for the performance improvement, particularly because it prevents the same string from being sanitized over and over in a big template with deep nesting.In most situations this change shouldn’t affect your code, but you must be aware of the following:
- Templates must not contain invalid XML characters, for example,
html`<p>A backspace: |\b|</p>`
. - Unsafe substitutions (those using
$${...}
) must not contain invalid XML characters. If the unsafe substitution is the result ofhtml`...`
itself, then it’s already sanitized; but if you’re generating HTML in some other way, then you may need to introduce sanitize-xml-string’ssanitizeXMLCharacters.sanitize()
.
Note: Safe substitutions (the default substitutions; those using
${...}
) continued to be sanitized against invalid XML characters. - Templates must not contain invalid XML characters, for example,