Definitions and Layouts
Use definitions and layouts with the current published Askr packages.
@askrjs/askr0.0.59
How to use definitions and layouts
Start with this complete definitions and layouts shape, then replace the example data and application service with your own.
- Import the published @askrjs/askr entrypoint.
- Keep definitions and layouts 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.
const registry = createRouteRegistry(() => {
group({ layout: AppLayout }, () => {
route('/', HomePage);
route('/projects/:projectId', ProjectPage);
});
});Route definitions
`route(path, Component, options?)` is the building block for a single URL: it returns a typed `RouteRef` you can later pass to `to()` for building destinations, and it accepts a `RouteOptions` object for loaders, policies, search-param schemas, and metadata. `page(path, Component, fn)` is the nested-route sibling — it declares a route at `path` and opens a child definition scope, so pages under it can add their own sub-routes or a layout. Both infer route params from the path string itself: writing `route('/posts/{slug}', ...)` gives the component a typed `slug: string` prop with no manual generic annotation needed.
Groups and layouts
A layout is just a component with a `children` prop, attached to a group via `GroupHelperOptions.layout` or to a page via the layout argument on `page()`. Askr stores it as a `LayoutScopeRecord` and composes it automatically at render time — you never call the layout component yourself. Layout composition happens outside the page chain: pages inside a group render first through `Outlet`, and the layout wraps that result, so a loading state or error inside a page doesn't require the layout to know anything about it.
Nested pages
`page()` lets a route own child routes: the `fn` argument is a definition callback where you call `route()` or nest further `page()` calls scoped under that parent path. Each nested route contributes to the same `RouteRecord.segments` matching logic, and Askr ranks routes by specificity so a literal segment like `/posts/new` wins over a param segment like `/posts/{id}` when both could match. `index(Component, options?)` fills the special case of "what renders at this path with nothing appended" — the default child when a parent route is visited directly.
Fallback routes
`fallback(Component)` registers the component Askr renders when no other route matches, and it's marked internally with `isFallback: true` on its `RouteRecord` so the router treats it distinctly from an ordinary catch-all. You get exactly one fallback per manifest — it's meant to be your app's 404 page, not a general-purpose wildcard route. If you need a wildcard that still participates in normal matching and layout composition, use a `*` or `{*splat}` path segment on a regular `route()` instead.