function / @typed/template/RenderTemplate

html

The main template tag function.

It creates a reactive Fx stream that renders the template. The actual rendering logic depends on the provided RenderTemplate service.

Package version
1.0.0-beta.7
Category
Template authoring
Since
1.0.0

Import

import { html } from "@typed/template/RenderTemplate";

Signatures

export declare function html<const Values extends ReadonlyArray<Renderable.Any>>(template: TemplateStringsArray, ...values: Values): Fx<RenderEvent, Renderable.Error<Values[number]>, Renderable.Services<Values[number]> | Scope | RenderTemplate>;

Why

html describes one renderer-independent template program. The RenderTemplate Effect service decides whether that program produces DOM for a browser, HTML chunks for SSR, or hydration against existing nodes. Dynamic values keep their own typed error and service channels instead of being hidden behind component state.

Ownership and lifetime

Calling the tag is inert. Rendering its returned Fx acquires dynamic values inside the running Effect Scope; interruption closes their subscriptions and finalizers. Each renderer owns only the dynamic parts it creates, leaving external classes, unowned DOM nodes, and native platform behavior intact.

Escaping and trust

Static template strings are authored markup. Ordinary interpolated strings are rendered as data, not treated as raw HTML. Renderer-owned HTML transport uses the separate branded HtmlRenderEvent boundary.

Examples

import { Effect } from "effect"
import { html } from "@typed/template"
import { DomRenderTemplate, render } from "@typed/template/Render"
import { Fx } from "@typed/fx"
import { Layer } from "effect"
import { RefSubject } from "@typed/fx/RefSubject"

// Simple static template
const staticTemplate = html`<div>Hello, world!</div>`

// Template with dynamic values
const name = "Alice"
const dynamicTemplate = html`<div>Hello, ${name}!</div>`

// Template with reactive values
const program = Effect.gen(function* () {
  const count = yield* RefSubject.make(0)

  const template = html`<div>
    <p>Count: ${count}</p>
    <button onclick=${RefSubject.increment(count)}>Increment</button>
  </div>`

  return yield* render(template, document.body).pipe(
    Fx.drainLayer,
    Layer.provide(DomRenderTemplate),
    Layer.launch
  )
})

Other public imports

These import paths expose the same declaration. Each page retains its own public name and signature.

Related reading

Source