hast utility to serialize hast nodes to HTML strings with comprehensive formatting options
npx @tessl/cli install tessl/npm-hast-util-to-html@9.0.0hast-util-to-html is a utility that converts hast (Hypertext Abstract Syntax Tree) nodes into HTML strings. It provides comprehensive serialization options for controlling HTML output formatting, making it suitable for both pretty-printing and minification use cases.
npm install hast-util-to-html
npm install hast-util-to-html @types/hastimport { toHtml } from "hast-util-to-html";For CommonJS:
const { toHtml } = require("hast-util-to-html");For TypeScript projects, you'll also need the hast type definitions:
import { toHtml } from "hast-util-to-html";
import type { Element, Root, Text } from "hast";import { h } from "hastscript";
import { toHtml } from "hast-util-to-html";
// Create hast tree
const tree = h(".alpha", [
"bravo ",
h("b", "charlie"),
" delta ",
h("a.echo", { download: true }, "foxtrot")
]);
// Convert to HTML
const html = toHtml(tree);
console.log(html);
// Output: <div class="alpha">bravo <b>charlie</b> delta <a class="echo" download>foxtrot</a></div>hast-util-to-html is part of the unified collective's syntax tree ecosystem. It works with hast (Hypertext Abstract Syntax Tree) nodes, which represent HTML structures in a standardized format. Typical workflow:
The serialization process handles node types like element, text, comment, doctype, raw, and root, providing extensive control over the HTML output format.
Converts hast nodes or node arrays into HTML strings with extensive formatting control.
function toHtml(
tree: Array<RootContent> | Nodes,
options?: Options
): string;Parameters:
tree: hast node or array of nodes to serializeoptions: Configuration object for controlling HTML output (optional)Returns: Serialized HTML string
Comprehensive configuration interface for customizing HTML serialization behavior.
interface Options {
allowDangerousCharacters?: boolean;
allowDangerousHtml?: boolean;
allowParseErrors?: boolean;
bogusComments?: boolean;
characterReferences?: CharacterReferences;
closeEmptyElements?: boolean;
closeSelfClosing?: boolean;
collapseEmptyAttributes?: boolean;
omitOptionalTags?: boolean;
preferUnquoted?: boolean;
quoteSmart?: boolean;
quote?: Quote;
space?: Space;
tightAttributes?: boolean;
tightCommaSeparatedLists?: boolean;
tightDoctype?: boolean;
tightSelfClosing?: boolean;
upperDoctype?: boolean;
voids?: ReadonlyArray<string>;
}Key Options:
allowDangerousCharacters (boolean, default: false): Do not encode some characters which cause XSS vulnerabilities in older browsersallowDangerousHtml (boolean, default: false): Allow raw nodes and insert them as raw HTMLallowParseErrors (boolean, default: false): Do not encode characters which cause parse errors to save bytesbogusComments (boolean, default: false): Use "bogus comments" instead of comments to save bytescharacterReferences (CharacterReferences): Configure how to serialize character referencescloseEmptyElements (boolean, default: false): Close SVG elements without content with slash on opening tagcloseSelfClosing (boolean, default: false): Close self-closing nodes with extra slashcollapseEmptyAttributes (boolean, default: false): Collapse empty attributes (get class instead of class="")omitOptionalTags (boolean, default: false): Omit optional opening and closing tagspreferUnquoted (boolean, default: false): Leave attributes unquoted if that results in less bytesquoteSmart (boolean, default: false): Use the other quote if that results in less bytesquote (Quote, default: '"'): Preferred quote to usespace (Space, default: 'html'): Namespace (html or svg)tightAttributes (boolean, default: false): Join attributes together without whitespacetightCommaSeparatedLists (boolean, default: false): Join comma-separated attribute values with just a commatightDoctype (boolean, default: false): Drop unneeded spaces in doctypestightSelfClosing (boolean, default: false): Do not use extra space when closing self-closing elementsupperDoctype (boolean, default: false): Use <!DOCTYPE… instead of <!doctype…voids (ReadonlyArray<string>): Tag names of elements to serialize without closing tagConfiguration for serializing character references in HTML output.
interface CharacterReferences {
useNamedReferences?: boolean;
omitOptionalSemicolons?: boolean;
useShortestReferences?: boolean;
}Fields:
useNamedReferences (boolean, default: false): Prefer named character references (&) where possibleomitOptionalSemicolons (boolean, default: false): Whether to omit semicolons when possibleuseShortestReferences (boolean, default: false): Prefer the shortest possible reference if that results in less bytesHTML quotes for attribute values.
type Quote = '"' | "'";Namespace specification for HTML or SVG serialization.
type Space = 'html' | 'svg';Core hast node types that can be serialized to HTML.
type Nodes = Root | Element | Text | Comment | Doctype;
interface Root {
type: 'root';
children: RootContent[];
}
interface Element {
type: 'element';
tagName: string;
properties?: Properties;
children: (Element | Text | Comment)[];
}
interface Text {
type: 'text';
value: string;
}
interface Comment {
type: 'comment';
value: string;
}
interface Doctype {
type: 'doctype';
name: string;
public?: string;
system?: string;
}
type RootContent = Element | Text | Comment | Doctype;
interface Properties {
[key: string]: boolean | null | number | string | (string | number)[];
}import { unified } from "unified";
import rehypeParse from "rehype-parse";
import { toHtml } from "hast-util-to-html";
// Parse HTML into hast tree
const processor = unified().use(rehypeParse, { fragment: true });
const tree = processor.parse('<p>Hello <strong>world</strong>!</p>');
// Serialize back to HTML with custom options
const html = toHtml(tree, {
allowDangerousHtml: false,
quote: '"',
quoteSmart: true
});
console.log(html);
// Output: <p>Hello <strong>world</strong>!</p>import { h } from "hastscript";
import { toHtml } from "hast-util-to-html";
const tree = h("article", [
h("h1", "Title"),
h("p", "Paragraph with ", h("strong", "bold"), " text.")
]);
const prettyHtml = toHtml(tree, {
allowParseErrors: false,
quote: '"',
space: 'html'
});
console.log(prettyHtml);
// <article><h1>Title</h1><p>Paragraph with <strong>bold</strong> text.</p></article>import { h } from "hastscript";
import { toHtml } from "hast-util-to-html";
const tree = h("div.container", [
h("button", { type: "submit", disabled: true }, "Submit"),
h("input", { type: "text", value: "" })
]);
const minifiedHtml = toHtml(tree, {
allowParseErrors: true,
bogusComments: true,
collapseEmptyAttributes: true,
omitOptionalTags: true,
preferUnquoted: true,
quoteSmart: true,
tightAttributes: true,
tightCommaSeparatedLists: true,
tightDoctype: true,
tightSelfClosing: true,
closeSelfClosing: true
});
console.log(minifiedHtml);
// <div class=container><button type=submit disabled>Submit</button><input type=text value=""/></div>import { s } from "hastscript/svg";
import { toHtml } from "hast-util-to-html";
const svgTree = s("svg", { viewBox: "0 0 100 100" }, [
s("circle", { cx: "50", cy: "50", r: "40", fill: "red" })
]);
const svgHtml = toHtml(svgTree, {
space: 'svg',
closeEmptyElements: true,
tightSelfClosing: false
});
console.log(svgHtml);
// <svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red" /></svg>import { h } from "hastscript";
import { toHtml } from "hast-util-to-html";
const tree = h("p", "This contains <special> & \"quoted\" characters");
const htmlWithNamedRefs = toHtml(tree, {
characterReferences: {
useNamedReferences: true,
omitOptionalSemicolons: false,
useShortestReferences: false
}
});
console.log(htmlWithNamedRefs);
// <p>This contains <special> & "quoted" characters</p>