agnostic/platform/dom

This module contains the DOM platform implementation and HTML-specific rendering utilities. The DOM platform provides the low-level mutation methods needed to render Lustre applications to the browser DOM.

For HTML serialization and SSR, see the SerializerConfig type and related functions like to_string and serialize.

Types

A type representing a DOM event in JavaScript.

pub type DomEvent

A type representing a DOM node in JavaScript.

pub type DomNode

Configuration for HTML serialization. Controls which elements are treated as void elements (no closing tag, like <br>) or self-closing tags (XML style, like <path />).

Use serializer_config to create a config with default HTML void elements, or empty_serializer_config to start from scratch. Convert to a Serializer using to_serializer.

pub opaque type SerializerConfig

Values

pub fn after_paint(
  effect: fn(fn(message) -> Nil, dynamic.Dynamic) -> Nil,
) -> effect.Effect(message)

Schedule a side effect that is guaranteed to run after the browser has painted the screen.

In addition to the dispatch function, your callback will also be provided with root element of your app or component. This is especially useful inside of components, giving you a reference to the Shadow Root.

Note: platforms that do not declare this phase — including server components — drop this effect and never run it.

pub const after_paint_phase: String

The phase name tagged by after_paint and declared by the DOM platform. Public so custom platforms can declare a Phase with this exact name to run after_paint effects.

pub fn attrs_to_string_tree(
  key: String,
  namespace: String,
  parent_namespace: String,
  attributes: List(vattr.Attribute(message)),
) -> string_tree.StringTree
pub fn before_paint(
  effect: fn(fn(message) -> Nil, dynamic.Dynamic) -> Nil,
) -> effect.Effect(message)

Schedule a side effect that is guaranteed to run after your view function is called and the DOM has been updated, but before the browser has painted the screen. This effect is useful when you need to read from the DOM or perform other operations that might affect the layout of your application.

In addition to the dispatch function, your callback will also be provided with root element of your app or component. This is especially useful inside of components, giving you a reference to the Shadow Root.

Messages dispatched immediately in this effect will trigger a second re-render of your application before the browser paints the screen. This let’s you read the state of the DOM, update your model, and then render a second time with the additional information.

Note: dispatching messages synchronously in this effect can lead to degraded performance if not used correctly. In the worst case you can lock up the browser and prevent it from painting the screen at all.

Note: platforms that do not declare this phase — including server components — drop this effect and never run it.

pub const before_paint_phase: String

The phase name tagged by before_paint and declared by the DOM platform. Public so custom platforms can declare a Phase with this exact name to run before_paint effects.

pub fn empty_serializer_config() -> SerializerConfig

Create an empty HTML config with no void elements and no self-closing tags. Use this as a starting point for custom configurations.

Example

let config = dom.empty_serializer_config()
  |> dom.with_self_closing_tags(["path", "circle", "rect"])
pub fn is_self_closing(
  config: SerializerConfig,
  tag: String,
) -> Bool

Check if a tag is a self-closing tag in this config.

pub fn is_void(
  config: SerializerConfig,
  tag: String,
  namespace: String,
) -> Bool

Check if a tag is a void element in this config. Only applies to elements in the default HTML namespace (empty string).

pub fn platform(
  onto target: String,
) -> Result(
  platform.Platform(
    DomNode,
    DomNode,
    DomNode,
    DomEvent,
    message,
    DomNode,
  ),
  platform.PlatformError,
)

Returns a Platform configured for the browser DOM. This is the standard platform used by client-side Lustre applications.

The target argument is a CSS selector used to locate the DOM element where the application will be mounted. The selector is resolved at construction time, and the resolved DOM node is stored as the platform’s target.

On Erlang this always returns Error(NotABrowser). On JavaScript this succeeds when running in a browser environment and the selector matches an element.

pub fn serialize(
  config: SerializerConfig,
  node: vnode.Element(message),
) -> String

Convert a Lustre Element to an HTML string using the given HTML config. This is not pretty-printed, so there are no newlines or indentation.

Example

let config = dom.serializer_config()
  |> dom.with_void("custom-void")
dom.serialize(config, element("custom-void", [], []))
// -> "<custom-void>"
pub fn serialize_tree(
  config: SerializerConfig,
  node: vnode.Element(message),
  parent_namespace: String,
) -> string_tree.StringTree

Convert a Lustre Element to an HTML StringTree using the given HTML config. This is more efficient than serialize when the output will be written to a socket or file.

pub fn serializer() -> serializer.Serializer(message)

Returns a Serializer that converts elements to HTML strings using the default HTML void elements. This is the standard serializer for server-side rendering.

Example

import agnostic/platform
import agnostic/platform/dom

let p = platform.headless(dom.serializer())
pub fn serializer_config() -> SerializerConfig

Create an HTML config with default void elements and no self-closing tags. This is the standard configuration for rendering HTML.

Example

let config = dom.serializer_config()
  |> dom.with_void("custom-void")
pub fn to_document_string(el: vnode.Element(message)) -> String

Converts an element to a string like to_string, but prepends a <!doctype html> declaration to the string. This is useful for rendering complete HTML documents.

If the provided element is not an html element, it will be wrapped in both a html and body element.

pub fn to_document_string_tree(
  el: vnode.Element(message),
) -> string_tree.StringTree

Converts a Lustre Element to an HTML StringTree, prepending a <!doctype html> declaration. This is useful for rendering complete HTML documents efficiently.

If the provided element is not an html element, it will be wrapped in both a html and body element.

pub fn to_readable_string(el: vnode.Element(message)) -> String

Converts a Lustre Element to a human-readable string by inserting new lines and indentation where appropriate. This is useful for debugging and testing.

pub fn to_serializer(
  config: SerializerConfig,
) -> serializer.Serializer(message)

Converts an SerializerConfig to a Serializer function.

Example

import agnostic/platform
import agnostic/platform/dom

let s = dom.serializer_config()
  |> dom.with_void("custom-void")
  |> dom.to_serializer()

let p = platform.headless(s)
pub fn to_snapshot(
  node: vnode.Element(message),
  debug: Bool,
) -> String

Convert an element to a snapshot string for testing. When debug is True, fragment and map markers are included in the output.

pub fn to_string(node: vnode.Element(message)) -> String

Convert a Lustre Element to an HTML string. This is not pretty-printed, so there are no newlines or indentation.

This uses the default HTML void elements. For custom void or self-closing configurations, use serialize with a custom SerializerConfig.

pub fn to_string_tree(
  node: vnode.Element(message),
  parent_namespace: String,
) -> string_tree.StringTree

Convert a Lustre Element to an HTML StringTree. This is more efficient than to_string when the output will be written to a socket or file.

This uses the default HTML void elements list. For custom void or self-closing configurations, use serialize_tree with a custom SerializerConfig.

pub fn with_self_closing(
  config: SerializerConfig,
  tag: String,
) -> SerializerConfig

Add a self-closing tag to the config. Self-closing tags render with XML-style self-closing syntax (e.g., <path /> instead of <path></path>).

pub fn with_self_closing_tags(
  config: SerializerConfig,
  tags: List(String),
) -> SerializerConfig

Add multiple self-closing tags to the config.

pub fn with_void(
  config: SerializerConfig,
  tag: String,
) -> SerializerConfig

Add a void element to the config. Void elements render without a closing tag (e.g., <br> instead of <br></br>).

pub fn with_void_elements(
  config: SerializerConfig,
  tags: List(String),
) -> SerializerConfig

Add multiple void elements to the config.

Search Document