# Rendering

> Choose client, server, streaming, hydration, or static delivery without changing the component model.

Source: [https://askrjs.com/docs/rendering](https://askrjs.com/docs/rendering)

Status: stable. Packages: @askrjs/askr.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Example

Keep the route tree shared and change the delivery adapter—not the component contract—when moving between client, server, and static rendering.

```tsx
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()`, `group()`, `createRouteRegistry()`) and consumed by whichever renderer you wire up. `RouteRegistry` is defined and exported from `@askrjs/askr/router` alone — `resolveRequest`, `createStaticGen`, and `createSPA` each import it from there and accept the same `registry` shape, rather than each renderer declaring its own competing type. 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.

## In this section

- [Client Rendering and Islands](https://askrjs.com/docs/rendering/client-and-islands/index.md): Boot a fully client-rendered app, or mount single interactive components into an otherwise static page.
- [Server-Side Rendering](https://askrjs.com/docs/rendering/server-side-rendering/index.md): Render a route to HTML on the server, including how request data and loader results reach the renderer.
- [Streaming and Deferred Boundaries](https://askrjs.com/docs/rendering/streaming/index.md): Stream a response so slow data arrives after the shell, without blocking the rest of the page.
- [Hydration](https://askrjs.com/docs/rendering/hydration/index.md): Attach the browser runtime to server-rendered markup, and verify the markup matches before it does.
- [Selective Hydration](https://askrjs.com/docs/rendering/selective-hydration/index.md): Defer hydration until idle or below the fold — worth reaching for only once profiling says hydration is the bottleneck.
- [Static Site Generation](https://askrjs.com/docs/rendering/static-site-generation/index.md): Render every route to HTML at build time and deploy the output as plain files with no server runtime.

## Documentation navigation

[Previous](https://askrjs.com/docs/data/actions-and-forms/index.md) | [Next](https://askrjs.com/docs/rendering/client-and-islands/index.md)
