DOCUMENTATION Docs Powered by Fuzor Docs

Runtime API

These modules run in the browser. The generated client already starts the router or mounts islands, so most apps only use a few of these functions from islands. Everything is typed; this page lists what each export is for.

Entry pointUse it for
fuzor/runtimeThe SPA router, navigation adapters, URL atoms, and re-exports of the two modules below
fuzor/runtime/islandsMounting islands yourself, island error handling, route params
fuzor/runtime/dataServer data in islands
fuzor/runtime/docs-uiShipped docs UI lifetime, deferred components, theme state and search (started automatically by docs mode)
fuzor/runtime/docs-searchStandalone Effect-owned docs search runtime
fuzor/ui/resumeDeferred component activation and Effect Atom checkpoints
fuzor/runtime/navigation, …/navigation/browser, …/history, …/hash, …/memory, …/coordinatorIndividual navigation pieces, for the smallest bundles

Router

getRouter(document?)

Returns the router started by the generated SPA client, or undefined in MPA builds and before it starts.

import { getRouter } from "fuzor/runtime";

const router = getRouter();
const outcome = await router?.navigate("/checkout/");
if (outcome?.status === "failed") console.error(outcome.error);

createRouter(outlet, options)

Creates a router for an outlet element. Only needed when you write your own client entry. Options:

OptionMeaning
islandsRegistry: island name → () => import(...)
baseDeployment base path, normally import.meta.env.BASE_URL
onErrorReceives route, island and data errors
islandTimeouts{ mountTimeoutMs, cleanupTimeoutMs }
navigationAn injected adapter, for tests or non-browser hosts
viewTransitionsAnimate page changes with the View Transitions API where supported
prefetch"intent": load a page's island modules on link hover or focus
acceptsUrlURL policy for custom protocols in embedded hosts

Router methods

MethodReturnsMeaning
start()Promise<() => Promise<void>>Starts routing; idempotent. The result stops it.
dispose()Promise<void>Stops routing and cleans up islands
navigate(href, options?)NavigationResultNavigates. Resolves to a NavigationOutcome when finished; .committed resolves when the URL changed. Options: history, state, scroll, focus, document. See navigating from code.
block(blocker)() => voidRegisters a navigation blocker; call the result to remove it
path(), subscribe(listener)route pathCurrent route path without base, such as /docs/
url(), subscribeUrl(listener)full URLIncluding query and hash
params(), subscribeParams(listener)Record<string, string>Dynamic route parameters
route(), subscribeRoute(listener)RouteMatch{ kind: "page" | "not-found", path, pattern?, params } of the current page
state(), subscribeState(listener)NavigationStatePhase of the latest navigation: requested, resolving, ready, committing, activating, completed, cancelled or failed, with route once resolved and error when failed
navigation()NavigationAdapterThe active adapter, for URL atoms

Subscriptions return a function that unsubscribes.

href(pattern, params?, options?)

Builds an app URL from a route or endpoint pattern and encodes its parameters. With the generated .fuzor/routes.d.ts, unknown patterns and missing or extra parameters are type errors. options: base, search (object or URLSearchParams), hash. See typed links.

FuzorRoutes is the interface the generated file augments, and RoutePattern the union of its keys (or string without it).

URL state

makeNavigationUrlAtom(navigation, key, schema, initialValue, options?)

An Effect that creates a schema-checked value stored in one query parameter. It lives in the surrounding Effect scope.

import * as Effect from "effect/Effect";
import * as Schema from "effect/Schema";
import { getRouter, makeNavigationUrlAtom } from "fuzor/runtime";

const program = Effect.scoped(Effect.gen(function* () {
  const page = yield* makeNavigationUrlAtom(getRouter()!.navigation()!, "page", Schema.Number, 1);
  page.subscribe(value => console.log("page", value));
  yield* page.set(2);            // replaces the history entry; pass "push" to add one
  yield* page.remove();          // deletes ?page
  yield* Effect.never;           // keep the atom alive
}));

Values are stored as JSON. Other query parameters, the hash and history state are preserved. Invalid or repeated values fail creation with UrlAtomError unless options.invalid is "default"; later invalid URLs keep the last valid value and call options.onError.

Islands

ExportMeaning
mountIslands(root, registry, onError?, options?)Mounts every <fuzor-island> below root; resolves to a cleanup function. options: signal, mountTimeoutMs, cleanupTimeoutMs. Used by MPA clients.
islandErrorHandlerThe default error UI with Try again, for onError
routeParams(element)Route parameters of the page containing element
reloadOnStaleDeployment(error)Reloads once when a chunk from an older build is gone; generated clients use it
IslandActivationErrorError passed to island error handlers

Islands also emit a bubbling fuzor:hydration-mismatch event with { island, framework, error } when a preview does not match the browser render; see islands.

An island module exports mount(host, props), which may return a cleanup function or a promise of one, and optionally render(props, { id }) returning HTML or a promise of HTML at build time. See writing an island adapter.

Server data

ExportMeaning
routeData(element)Promise of the server data for the page containing element; shares the page's request
loadRouteData(outlet, options?)Starts or restarts the request; options.search, options.fetch
abortRouteData(outlet)Cancels a pending request
fillDataSlots(root, data)Fills <fuzor-data> slots
RouteDataErrorFailed request, with the HTTP status when there was a response

See server data.

The router picks an adapter automatically: the browser Navigation API where available, the History API elsewhere, and fragment (hash) routing for file: or custom-protocol documents. For tests and non-browser hosts, create one yourself:

import * as Effect from "effect/Effect";
import { createRouter, makeMemoryNavigation } from "fuzor/runtime";

const navigation = await Effect.runPromise(makeMemoryNavigation({ baseUrl: "https://app.test/", initialEntries: [{ href: "/about/" }] }));
const router = createRouter(outlet, { navigation, islands });
ExportMeaning
NavigationThe Effect service key for a NavigationAdapter
makeBrowserNavigation, BrowserNavigationLive, supportsBrowserNavigation, navigationBrowser, navigateDocumentNavigation API adapter and helpers
makeHistoryNavigation, HistoryNavigationLiveHistory API adapter
makeHashNavigation, HashNavigationLiveFragment adapter for embedded documents
makeMemoryNavigation, MemoryNavigationLiveIn-memory adapter
makeNavigationCoordinator, coordinateNavigationLifecycle orchestration used by the router
NavigationError, NavigationLifecycleErrorTyped adapter and lifecycle failures

Capacitor integration

import { App } from "@capacitor/app";
import { connectCapacitor, defaultDeepLink } from "fuzor/runtime/capacitor";

// Connects the started SPA router to Capacitor:
const disconnect = await connectCapacitor({
  app: App,
  rootBack: "exit", // "exit" (default) or "minimize" on the first page
  deepLink: defaultDeepLink // optional custom URL mapping
});
ExportMeaning
connectCapacitor(options)Connects deep links (launch URL and appUrlOpen), Android hardware Back button through the router with blockers, and foreground resume to the Fuzor router. Launch URLs are applied once per session so reloads preserve the current page. Resolves to a cleanup function that removes listeners.
defaultDeepLink(url)Maps custom schemes (e.g. myapp://about) and App Links (https://...) to app routes.

URL helpers

routeKey(pathname) and normalizePath(path) apply Fuzor's URL matching rules. normalizeBase, stripBase and withBase convert between app paths and deployment-base paths.

Built with Fuzor Back to top ↑
On this page Back to top ↑