Client Rendering and Islands
Boot a fully client-rendered app, or mount single interactive components into an otherwise static page.
Example
Keep the route tree shared and change the delivery adapter—not the component contract—when moving between client, server, and static rendering.
import { createSPA, hydrateSPA } from '@askrjs/askr/boot';
const root = document.getElementById('app')!;
if (root.childNodes.length) {
await hydrateSPA({ root, registry });
} else {
await createSPA({ root, registry });
}SPA boot
`createSPA` from `@askrjs/askr/boot` mounts a fully client-rendered app into a root element and initializes the router from the `registry` you built with `createRouteRegistry()`. It accepts `auth`, `scrollRestoration`, and `cleanupStrict` alongside the registry, and returns a `Promise<void>` that resolves once the initial route has mounted.
Client boundaries
`hydrateSPA` is the counterpart used when the server already produced markup: it takes the same route source shape as `createSPA` plus a `hydrate` block (`verifyMarkup`, `deferUntilIdle`, `deferBelowFold`, `foldThreshold`, `skipSelectors`) that controls how aggressively hydration is deferred. Both functions live under `@askrjs/askr/boot`, keeping the split between "boot fresh" and "attach to existing DOM" as two distinct, narrow entry points rather than one flag-driven function.
Island ownership
`createIsland` enhances a single existing DOM node with one component and mounts once — no router involved. `createIslands` does the same for a list of `{ root, component }` pairs in one call and is documented on the function itself as "the only public islands constructor," meaning multi-island pages should go through it rather than calling `createIsland` in a loop. Neither function touches routing state, so islands stay independent of whatever else is on the page.
When to choose client rendering
Pick `createSPA` when the whole page is interactive and there's no server response to enhance — dashboards, authenticated tools, anything behind a login wall where SEO and first-paint latency matter less. Pick islands (`createIsland`/`createIslands`) when most of the page is static content and only a widget or two needs `state()` and event handlers. If server-rendered markup already exists and needs to become interactive without a full remount, `hydrateSPA` is the right call instead of either.