RouteOptions
Options of defineRoute.
Options of defineRoute.
Import#
ts
import type { RouteOptions } from "@shadow-js/router";
Signature#
ts
interface RouteOptions<P extends string, S, L> {
/** Route id. Defaults to the path. Required for a pathless route (`""`). */
readonly id?: string;
/** Child routes, with paths relative to this route. */
readonly children?: readonly RouteDefinition[];
/** Renders the route. Its `<Outlet />` shows the child route. */
readonly component?: RouteComponent;
/** Shown while navigating into this route, after `pendingMs`, when its data is not cached. */
readonly pending?: () => unknown;
/**
* Delay, in ms, before this route's pending UI shows (Next's `loading.tsx` is immediate at `0`). It
* applies to a navigation whose deepest matched route sets it, and to the children of a route that sets
* it that do not set their own. Default: the router's `pendingMs` (1000).
*/
readonly pendingMs?: number;
/**
* Shown in place of the route when its loader or component throws. Resets on navigation. Needs the
* `errors` feature (`errorBoundaries()` from `@shadow-js/router/errors`).
*/
readonly error?: (props: RouteErrorProps) => unknown;
/**
* Shown when `notFound()` is thrown at or below this route. A route with child routes (a
* layout) stays on screen and this takes the place of its `<Outlet />`; a route without children
* is replaced by it. A root layout's `notFound` is also what a URL that matches no route shows.
*/
readonly notFound?: () => unknown;
/**
* Parses and validates the query: a function, or a Standard Schema (Zod, Valibot, ArkType) whose output is the typed
* search. A throw fails the navigation (no commit); a rejected query throws `SearchValidationError`.
*/
readonly validateSearch?: SearchValidator<S>;
/** Extra keys of the loader cache, computed from the validated search. */
readonly loaderDeps?: (search: S) => unknown;
/**
* Rules for the params of this path (`{ id: /^\d+$/ }`, `{ lang: ["en", "ar"] }`, a predicate or a
* Standard Schema). A value that fails its rule does not match: the next route is tried, and a URL
* with no matching route is not found. Links built with `params` are checked the same way.
*/
/** Needs the `filters` feature (`matchFilters()` from `@shadow-js/router/filters`). */
readonly matchFilters?: { readonly [K in keyof ParamsView<P>]?: ParamFilter };
/** Runs top-down before the loaders, may add context, may throw `redirect()` / `notFound()`. */
readonly beforeLoad?: (args: RouteArgs<P, S>) => BeforeLoadResult | Promise<BeforeLoadResult>;
/**
* Loads data for this route. Loaders run in parallel. Their result is `useLoaderData()`. Needs the
* `loaders` feature (`loaderCache()` from `@shadow-js/router/loaders`).
*/
readonly loader?: (args: LoaderArgs<P, S>) => L | Promise<L>;
/**
* Document head for this route, applied with `useHead` while the route is rendered. Needs the `head`
* feature (`headManagement()` from `@shadow-js/router/head`).
*/
readonly head?: (args: {
readonly params: ParamsView<P>;
readonly loaderData: L | undefined;
}) => RouteHeadInput;
/** Tags for future invalidation filters. */
readonly tags?: readonly string[];
/**
* Where the route renders, read by the server handler of Dusk (the router itself does
* not use it). `true` (the default): the server renders the route. `false`: the server sends the
* empty document shell and the browser renders and loads everything. `"data-only"`: the server
* runs the loaders and sends their data with an empty document, and the browser renders. In a
* chain of matched routes the most restrictive value wins (`false`, then `"data-only"`).
*/
readonly ssr?: boolean | "data-only";
/**
* What the server does with a param the page's `prerender` export does not list. `true` (the default): the page
* renders on request. `false`: the server answers not found (a 404 with the app's not-found UI). Read by the
* server handler of Dusk; the router itself does not use it, so a navigation in the browser is not refused. Written
* by the generated route tree from `export const dynamicParams = true | false`, which needs a `prerender` export.
*/
readonly dynamicParams?: boolean;
/**
* Seconds a server-rendered response of this page may be served from the ISR cache before it is
* regenerated, or `false` to keep it until it is purged (`revalidatePath` / `revalidateTag`). Read
* by the server handler of Dusk; the router itself does not use it. In a chain of matched
* routes the shortest value wins.
*/
readonly revalidate?: number | false;
/**
* Cache options of the page: `staleSeconds` (how long a stale response may still be served while it
* is regenerated in the background), `cookies` (cookies the response may depend on; such requests are
* cached per value) and `searchParams` (the query parameters that take part in the cache key; all
* when omitted). Read by the server handler of Dusk.
*/
readonly cache?: RouteCacheOptions;
/**
* `"blocking"` (the default) waits for a fresh loader result on navigation; `"background"`
* shows the cached value at once and refreshes it without updating the screen.
*/
readonly staleReload?: "background" | "blocking";
/**
* Document metadata exports (`metadata`, `generateMetadata`, `viewport`, `generateViewport`, `links`,
* `meta`, `headers`). The router does not read them: a metadata feature (Dusk's `duskFeatures()`) does,
* through the `metadata` capability. A route that exports one needs that feature. Written by the generator.
* @internal
*/
readonly metadata?: unknown;
readonly generateMetadata?: unknown;
/** The metadata of the not-found UI (`notFound`) of this route, merged over the chain of the 404 (see dusk-metadata). */
readonly notFoundMetadata?: unknown;
/** The metadata of the error UI (`error`) of this route, merged over the chain of an error status. */
readonly errorMetadata?: unknown;
readonly viewport?: unknown;
readonly generateViewport?: unknown;
readonly links?: unknown;
readonly meta?: unknown;
readonly headers?: unknown;
/**
* Set by the generated route tree when this route's chain runs server middleware (its own
* `middleware` export, or a `_middleware` file in a folder above it). The middleware itself is
* server-only and never reaches the client; the Dusk client asks the server to run it before a
* navigation into the route. Written by the generator, not by hand.
* @internal
*/
readonly serverMiddleware?: boolean;
}
Members#
| Name | Type | Description |
|---|---|---|
P |
P extends string |
|
S |
S |
|
L |
L |
|
id? |
readonly id?: string |
Route id. Defaults to the path. Required for a pathless route (""). |
children? |
readonly children?: readonly RouteDefinition[] |
Child routes, with paths relative to this route. |
component? |
readonly component?: RouteComponent |
Renders the route. Its <Outlet /> shows the child route. |
pending? |
readonly pending?: () => unknown |
Shown while navigating into this route, after pendingMs, when its data is not cached. |
pendingMs? |
readonly pendingMs?: number |
Delay, in ms, before this route's pending UI shows (Next's loading.tsx is immediate at 0). It applies to a navigation whose deepest matched route sets it, and to the children of a route that sets it that do not set their own. Default: the router's pendingMs (1000). |
error? |
readonly error?: (props: RouteErrorProps) => unknown |
Shown in place of the route when its loader or component throws. Resets on navigation. Needs the errors feature (errorBoundaries() from @shadow-js/router/errors). |
notFound? |
readonly notFound?: () => unknown |
Shown when notFound() is thrown at or below this route. A route with child routes (a layout) stays on screen and this takes the place of its <Outlet />; a route without children is replaced by it. A root layout's notFound is also what a URL that matches no route shows. |
validateSearch? |
readonly validateSearch?: SearchValidator<S> |
Parses and validates the query: a function, or a Standard Schema (Zod, Valibot, ArkType) whose output is the typed search. A throw fails the navigation (no commit); a rejected query throws SearchValidationError. |
loaderDeps? |
readonly loaderDeps?: (search: S) => unknown |
Extra keys of the loader cache, computed from the validated search. |
matchFilters? |
readonly matchFilters?: { readonly [K in keyof ParamsView<P>]?: ParamFilter } |
Needs the filters feature (matchFilters() from @shadow-js/router/filters). |
beforeLoad? |
readonly beforeLoad?: (args: RouteArgs<P, S>) => BeforeLoadResult | Promise<BeforeLoadResult> |
Runs top-down before the loaders, may add context, may throw redirect() / notFound(). |
loader? |
readonly loader?: (args: LoaderArgs<P, S>) => L | Promise<L> |
Loads data for this route. Loaders run in parallel. Their result is useLoaderData(). Needs the loaders feature (loaderCache() from @shadow-js/router/loaders). |
head? |
readonly head?: (args: { readonly params: ParamsView<P>; readonly loaderData: L | undefined; }) => RouteHeadInput |
Document head for this route, applied with useHead while the route is rendered. Needs the head feature (headManagement() from @shadow-js/router/head). |
tags? |
readonly tags?: readonly string[] |
Tags for future invalidation filters. |
ssr? |
readonly ssr?: boolean | "data-only" |
Where the route renders, read by the server handler of Dusk (the router itself does not use it). true (the default): the server renders the route. false: the server sends the empty document shell and the browser renders and loads everything. "data-only": the server runs the loaders and sends their data with an empty document, and the browser renders. In a chain of matched routes the most restrictive value wins (false, then "data-only"). |
dynamicParams? |
readonly dynamicParams?: boolean |
What the server does with a param the page's prerender export does not list. true (the default): the page renders on request. false: the server answers not found (a 404 with the app's not-found UI). Read by the server handler of Dusk; the router itself does not use it, so a navigation in the browser is not refused. Written by the generated route tree from export const dynamicParams = true | false, which needs a prerender export. |
revalidate? |
readonly revalidate?: number | false |
Seconds a server-rendered response of this page may be served from the ISR cache before it is regenerated, or false to keep it until it is purged (revalidatePath / revalidateTag). Read by the server handler of Dusk; the router itself does not use it. In a chain of matched routes the shortest value wins. |
cache? |
readonly cache?: RouteCacheOptions |
Cache options of the page: staleSeconds (how long a stale response may still be served while it is regenerated in the background), cookies (cookies the response may depend on; such requests are cached per value) and searchParams (the query parameters that take part in the cache key; all when omitted). Read by the server handler of Dusk. |
staleReload? |
readonly staleReload?: "background" | "blocking" |
"blocking" (the default) waits for a fresh loader result on navigation; "background" shows the cached value at once and refreshes it without updating the screen. |
metadata? |
readonly metadata?: unknown |
Document metadata exports (metadata, generateMetadata, viewport, generateViewport, links, meta, headers). The router does not read them: a metadata feature (Dusk's duskFeatures()) does, through the metadata capability. A route that exports one needs that feature. Written by the generator. |
generateMetadata? |
readonly generateMetadata?: unknown |
|
notFoundMetadata? |
readonly notFoundMetadata?: unknown |
The metadata of the not-found UI (notFound) of this route, merged over the chain of the 404 (see dusk-metadata). |
errorMetadata? |
readonly errorMetadata?: unknown |
The metadata of the error UI (error) of this route, merged over the chain of an error status. |
viewport? |
readonly viewport?: unknown |
|
generateViewport? |
readonly generateViewport?: unknown |
|
links? |
readonly links?: unknown |
|
meta? |
readonly meta?: unknown |
|
headers? |
readonly headers?: unknown |
|
serverMiddleware? |
readonly serverMiddleware?: boolean |
Set by the generated route tree when this route's chain runs server middleware (its own middleware export, or a _middleware file in a folder above it). The middleware itself is server-only and never reaches the client; the Dusk client asks the server to run it before a navigation into the route. Written by the generator, not by hand. |