Import
import { renderToHtml } from "@typed/template/Html";Signatures
export declare function renderToHtml<const T extends Renderable.Any>(renderable: T): Fx.Fx<string, Renderable.Error<T>, Renderable.Services<T>>;Why
This keeps SSR push-based: each ordered renderer-owned HTML event becomes an output chunk as it arrives. Unlike DOM rendering, dynamic inputs use the HTML layer’s single-value computed behavior and do not remain live.
Ownership and lifetime
The returned Fx owns no response by itself. Its running Effect Scope owns subscriptions and interruption; the caller owns the HTTP response or other sink consuming the strings. Typed errors and required services are preserved.
Trust boundary
Ordinary dynamic template data is contextually escaped. Branded
HtmlRenderEvent values are trusted renderer output, not a raw-HTML API.
Examples
import { Effect } from "effect"
import { html } from "@typed/template"
import { renderToHtml, HtmlRenderTemplate } from "@typed/template/Html"
import { Fx } from "@typed/fx"
const program = Effect.scoped(Effect.gen(function* () {
const template = html`<div>Hello, ${"world"}!</div>`
// Render to HTML string stream
const htmlStream = renderToHtml(template).pipe(
Fx.provide(HtmlRenderTemplate)
)
// Collect all HTML chunks
const chunks = yield* Fx.collectAll(htmlStream)
console.log(chunks.join("")) // "<div>Hello, world!</div>"
}))Other public imports
These import paths expose the same declaration. Each page retains its own public name and signature.