Rendering
Choose client, server, streaming, hydration, or static delivery without changing the component model.
@askrjs/askr0.0.59
How to use rendering
Keep the route tree shared and change the delivery adapter—not the component contract—when moving between client, server, and static rendering.
- Import the published @askrjs/askr entrypoint.
- Keep rendering configuration next to the component, route, or server composition root that owns it.
- Handle pending, unavailable, cancellation, and failure states, then verify the production path.
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 });
}Delivery matrix
Askr renders the same component tree through five paths: pure client SPA, server-side rendering per request, streaming SSR with deferred boundaries, static site generation at build time, and selective hydration of islands inside otherwise static markup. Each path is a different entry point (`createSPA`, `renderRouteRequest`, `renderToStream`, `createStaticGen`, `createIsland`/`createIslands`) rather than a different component API, so a page written against `state()` and JSX works unchanged regardless of which one invokes it. Picking a path is a deployment decision, not a rewrite.
Shared application model
Routes, components, and data loaders are defined once through the router DSL (`route()`, `registerRoutes()`, `getManifest()`) and consumed by whichever renderer you wire up. `RouteHandler` and `RouteRegistry` show up identically in `@askrjs/askr/ssr`, `@askrjs/askr/ssg`, and `@askrjs/askr/boot`, which is why `resolveRequest`, `createStaticGen`, and `createSPA` all accept the same `registry` or `routes` shape. Swapping SSR for SSG in production means changing which function calls your routes, not restructuring them.
Document ownership
Every path that produces full HTML — SSR, streaming, and SSG — takes an optional `document: DocumentRenderer`, a function of `{ appHtml, context }` that returns the final HTML string. `DocumentRenderContext` carries `mode` ('ssr' or 'ssg'), the URL, route params, and the render `seed`, so a single document template can brand output differently per mode if needed. Client-only boot (`createSPA`) has no document renderer because it mounts into an existing page shell instead of producing one.
Selection checklist
Reach for SSG when route output doesn't depend on the requesting user and can be precomputed with `createStaticGen`; reach for SSR (`renderRouteRequest`) when it does. Add streaming (`renderToStream`) once a page has slow data that shouldn't block the rest of the response, and add islands (`createIsland`) when only a fragment of an otherwise static page needs interactivity. Selective hydration is worth reaching for only after profiling shows hydration cost is the bottleneck — it's still a limited feature and shouldn't be the default choice.