js/ui/html

js/ui/html.ts

fino:ui/html — render host-neutral Fino VNodes to HTML strings.

This module is the server-side serializer for fino:ui trees. It does not retain component state or reconcile trees; each call walks the supplied VNode and returns a complete HTML string. Use it for server-rendered pages, emails, and server-driven UI regions that will be patched into a browser later.

Design

Text and attribute values are escaped with fino:template's HTML escaping. Boolean attributes render only when true, className maps to class, style objects become CSS declarations, and function props throw because server HTML cannot preserve event handlers. rawHtml() is the explicit escape hatch for trusted markup.

/** @jsxImportSource fino:ui *\/
import { renderToHtml } from 'fino:ui/html';

const html = renderToHtml(<button disabled>Save</button>);

Constants

const RAW_HTML_TYPE

Element type carrying pre-rendered markup.

The name is namespaced so it cannot collide with an HTML tag, and a host that does not trust its trees can refuse this type by name.

Functions

function rawHtml(html: string): VNode

Mark a trusted string as raw HTML.

Raw HTML is inserted without escaping. Only pass strings produced by trusted code or an HTML sanitizer.

The result is an ordinary VNode holding plain JSON props, so pre-rendered markup survives serialization the same as any other node: it can cross a realm boundary, ride the portable protocol, and be rejected by name on a host that will not inline markup.

import { h } from 'fino:ui';
import { rawHtml, renderToHtml } from 'fino:ui/html';

const html = renderToHtml(h('div', null, rawHtml('<span>ok</span>')));

function renderToHtml(vnode: VNode): string

Render one Fino UI VNode to an HTML string.

The serializer accepts trees produced by h() or the JSX runtime. Fragments render their children without a wrapper. Void elements never receive closing tags.

Text and attribute values are escaped. Function-valued props throw because they cannot be represented in static HTML; use server-driven actions or a client runtime rather than embedding handlers.

import { h } from 'fino:ui';
import { renderToHtml } from 'fino:ui/html';

const html = renderToHtml(h('input', { name: 'q', value: 'a&b' }));

function htmlSink(): Sink<string>

Sink that serializes each committed tree to an HTML string.

Pair it with renderStatic() for a page built once, or with createRoot() when a caller wants fresh markup on every state change.

import { h, renderStatic } from 'fino:ui';
import { htmlSink } from 'fino:ui/html';

const html = renderStatic(() => h('main', null, 'Ready'), htmlSink());