Askr documentation
Routing & Data

Routing

Define typed routes, layouts, navigation, loaders, policies, and metadata.

Example

Register a route once and let the same registry drive browser navigation, SSR, and static generation.

import { createRouteRegistry, group, route } from '@askrjs/askr/router';

export const registry = createRouteRegistry(() => {
  group({ layout: AppLayout }, () => {
    route('/', HomePage);
  route('/projects/{projectId}', ProjectPage);
  });
});

Published props

Generated from the TypeScript declarations shipped by the installed package. Named types in the Type column define the accepted values.

LinkProps

Import from @askrjs/askr/router.

PropTypeDefaultDescription
aria-currentaria-current?: "page" | "step" | "location" | "date" | "time" | "true" | "false" | undefined;Optional aria-current attribute for indicating current page/location. Use "page" for the current page in navigation.
aria-labelaria-label?: string | undefined;Optional aria-label for accessibility when link text isn't descriptive enough.
childrenchildren?: RenderableChild;
classclass?: string | undefined;
hrefhref?: string | undefined;
onClickonClick?: ((event: MouseEvent) => void) | undefined;
onPressonPress?: ((event: Event) => void) | undefined;
relrel?: string | undefined;Optional rel attribute for link relationships. Common values: "noopener", "noreferrer", "nofollow"
targettarget?: string | undefined;Optional target attribute. Use "_blank" for new tab/window.
toto?: RouteDestination | undefined;

ResolveProps

Import from @askrjs/askr/router.

PropTypeDefaultDescription
childrenchildren: (value: T) => RenderableChild;
pendingpending?: RenderableChild;
rejectedrejected?: RenderableChild | ((error: unknown) => RenderableChild);
valuevalue: Deferred<T>;

Route registry

Every route in an Askr app is declared through `createRouteRegistry()`, which takes a definition function and returns a `RouteRegistry` built by calling `route()`, `page()`, `group()`, `index()`, and `fallback()` inside that function. The registry is an ordinary value: export it, then hand it to `createSPA`, `hydrateSPA`, `createStaticGen`, or `renderToString`, so client rendering, hydration, SSG, and SSR all read the same declaration. Because nothing is stored globally, two registries can coexist — which is what lets a static build settle its own route tree without disturbing the one the browser boots from, and what keeps a server rendering concurrent requests off shared mutable state.

Route groups

`group(options, fn)` nests a block of route declarations under a shared layout and shared access rules without repeating them on every child route. The `layout` you pass in `GroupHelperOptions` wraps whatever the group renders, and `auth`/`policies` on the group apply to every route declared inside its callback. Groups compose: nesting one group inside another builds up a `layoutChain` and a merged set of policies that Askr walks top-down when it resolves a request, so a route three groups deep still only needs to declare what's specific to it.

A navigation in Askr resolves through `resolveRouteRequest()`, which matches the target against the app's explicit `RouteRegistry` and returns either a `RouteRenderResult`, an `AccessRedirectDecision`, an `AccessDenyDecision`, or `null` if nothing matches. That result already reflects any policy checks — redirects and denials are decided before a component ever renders, not caught afterward. Each `RouteContext` handed through the pipeline carries an `AbortSignal`, so loaders and preload functions tied to a route that gets superseded by a newer navigation can be cancelled instead of racing to finish and clobber the current view.

Delivery modes

`RouteMode` is one of `'spa'`, `'ssr'`, or `'ssg'`, and it's threaded through `RouteContext` so a loader or a policy can behave differently depending on how the current request is being served. The same route declarations work across all three modes — you don't write separate route trees for server rendering versus the client. SSG specifically leans on the `entries` option in `RouteOptions`, which returns the list of param combinations to pre-render as static pages at build time.