DocsGo further

Go further

Browser interop

Reach the browser when the browser is the right place to work. Use JavaScript hooks or Java closures compiled to WebAssembly.

Browse documentation

Mount a client hook

Add data-jsp-hook to an element and register the hook in a page script. mounted, updated, and destroyed follow that element’s lifetime. Use hooks for canvas, layout reads, or existing JavaScript widgets.

ctx.pushEvent dispatches a bubbling custom event that the template can bind normally. Hook parameters can be supplied through data-jsp-hook-params as JSON.

static/chart.js
jaspring.hooks.register('chart', {
  mounted(el, ctx) {
    el.onclick = () => ctx.pushEvent('point-picked', { index: 2 });
  },
  updated(el, ctx) { /* redraw using ctx.params */ },
  destroyed(el) { /* release client resources */ }
});

Ask the browser for a result

Register a page-level JavaScript function with jaspring.calls.register, then call it from Java using Browser.current().call. A dotted target such as chart.size calls a method on a mounted hook in the component’s host.

The result completes inside a page turn, so its continuation may safely update signals. A missing function, client error, or timeout fails the task.

A browser round trip
// JavaScript
jaspring.calls.register('viewport', () => ({ width: innerWidth }));

// Java, inside a component handler
Browser.current().call("viewport")
        .thenAccept(value -> status.set(String.valueOf(value)));

Run a Java closure in the browser

Platform.onBrowser takes a Java lambda that receives a BrowserClient. The Gradle plugin compiles these closures into one WebAssembly module using GraalVM Web Image. The result travels back through the same page protocol.

Browser closures cannot access this, Spring beans, server signals, or secrets. Capture only serializable data. Supported values include primitives, strings, enums, records, and arrays; use records to carry typed collections.

Read browser storage
Platform.onBrowser(client ->
        client.localStorage().get("theme").orElse("dark"))
        .thenAccept(theme::set);

The optional WebAssembly toolchain

Browser closures require Oracle GraalVM 25.2.x with Web Image, Binaryen wasm-as 119 or later, and the matching Jaspring Gradle plugin. GraalVM Community does not include Web Image.

The plugin scans closures, builds a dispatcher, and packages the launcher, WebAssembly module, and manifest as application resources. Set -Pjaspring.browser.skip=true to build without the image; invoking a closure then reports that the build is unavailable.

Jaspring · release + master guidesRead the framework source