hast-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-htmlnpm 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
elementtextcommentdoctyperawrootConverts hast nodes or node arrays into HTML strings with extensive formatting control.
function toHtml(
tree: Array<RootContent> | Nodes,
options?: Options
): string;Parameters:
treeoptionsReturns: 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:
allowDangerousCharactersbooleanfalseallowDangerousHtmlbooleanfalserawallowParseErrorsbooleanfalsebogusCommentsbooleanfalsecharacterReferencesCharacterReferencescloseEmptyElementsbooleanfalsecloseSelfClosingbooleanfalsecollapseEmptyAttributesbooleanfalseclassclass=""omitOptionalTagsbooleanfalsepreferUnquotedbooleanfalsequoteSmartbooleanfalsequoteQuote'"'spaceSpace'html'tightAttributesbooleanfalsetightCommaSeparatedListsbooleanfalsetightDoctypebooleanfalsetightSelfClosingbooleanfalseupperDoctypebooleanfalse<!DOCTYPE…<!doctype…voidsReadonlyArray<string>Configuration for serializing character references in HTML output.
interface CharacterReferences {
useNamedReferences?: boolean;
omitOptionalSemicolons?: boolean;
useShortestReferences?: boolean;
}Fields:
useNamedReferencesbooleanfalse&omitOptionalSemicolonsbooleanfalseuseShortestReferencesbooleanfalseHTML 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>