WebUI WebAssembly Handler #

The WebUI WASM handler compiles the full rendering pipeline to WebAssembly via wasm-bindgen, enabling client-side rendering directly in the browser. It powers the interactive Playground in the documentation site.

How It Works #

The WASM module includes the real webui-parser and webui-handler - the same code used by the CLI and the Rust handler. This means templates parsed in the browser produce identical output to server-side rendering.

Two modes of operation are available:

  1. render - Takes a pre-built protocol (JSON) + state and renders HTML
  2. build_and_render - Takes virtual files + state, parses and renders in one call

Building the WASM Module #

cargo xtask build-wasm

The output is committed to the repository under docs/ for use by the playground. Most developers don't need to rebuild it - only rebuild when you change Rust code in the core crates.

API Reference #

#

Render a pre-built WebUI protocol with state data.

import init, { render } from './webui_wasm.js';

await init();

const protocolJson = '{"fragments": {...}}';
const stateJson = '{"title": "Hello"}';

const html = render(protocolJson, stateJson);

Parameters:

ParameterTypeDescription
protocolJsonstringJSON-serialized WebUIProtocol
stateJsonstringJSON string with the render state
pluginstring | undefinedOptional plugin identifier (e.g., "fast-v3")

Returns: Rendered HTML string. Throws on error.

#

Parse virtual files and render in a single call. This is the primary API for the playground, where no filesystem is available.

import init, { build_and_render } from './webui_wasm.js';

await init();

const files = {
  'index.html': '<h1>Hello, {{name}}!</h1>',
  'my-card.html': '<div class="card"><slot></slot></div>',
  'my-card.css': '.card { border: 1px solid #ccc; }'
};
const stateJson = '{"name": "WebUI"}';

const html = build_and_render(files, stateJson, 'index.html');
// โ†’ '<h1>Hello, WebUI!</h1>'

Parameters:

ParameterTypeDescription
filesRecord<string, string>Map of filenames to content
stateJsonstringJSON string with the render state
entrystringEntry HTML filename (e.g., "index.html")

Returns: Rendered HTML string. Throws on error.

Component discovery: HTML files with a hyphen in the name are automatically registered as components (e.g., my-card.html โ†’ <my-card>). Matching .css files are paired and inlined via <style> tags.

#

Parse virtual files into a WebUI protocol without rendering. Returns the serialized protocol as a JSON string.

import init, { build_protocol } from './webui_wasm.js';

await init();

const files = {
  'index.html': '<h1>{{title}}</h1>'
};

const protocolJson = build_protocol(files, 'index.html');
// Use with render() later

Parameters:

ParameterTypeDescription
filesRecord<string, string>Map of filenames to content
entrystringEntry HTML filename

Returns: JSON string of the WebUIProtocol.

Using Plugins #

Pass "fast-v3" as the plugin parameter to enable @microsoft/fast-element 3.x hydration markers:

const html = render(protocolJson, stateJson, 'fast-v3');

Deprecated "fast" and "fast-v2" identifiers remain available for @microsoft/fast-element 2.x compatibility markers. See Plugins for details on what markers are injected.

Playground Integration #

The documentation playground uses build_and_render to provide a live editing experience:

  1. User edits template HTML, component files, and state JSON in the browser
  2. On each change, build_and_render is called with the virtual files
  3. The rendered HTML is displayed in a preview pane

This provides instant feedback with the exact same parser and handler used in production builds.

Differences from Server-Side Rendering #

AspectServer (CLI / Rust / Node)WASM (Browser)
Protocol formatProtobuf binaryJSON
CSS strategyLink (default) or styleAlways inline
File I/OFilesystemVirtual file map
StreamingYes (callback-based)No (returns full string)
Plugin supportYesYes