Askr
Routing & Data

Route Metadata

Use route metadata with the current published Askr packages.

  • @askrjs/askr0.0.59

How to use route metadata

Attach title and description metadata to the route so SSG and browser navigation use the same document contract.

  1. Import the published @askrjs/askr entrypoint.
  2. Keep route metadata configuration next to the component, route, or server composition root that owns it.
  3. Handle pending, unavailable, cancellation, and failure states, then verify the production path.
route('/projects/:projectId', ProjectPage, {
  meta: ({ data }) => ({
    title: data.project.name + ' | Projects',
    description: data.project.summary,
  }),
});

Static metadata

`RouteMeta` covers `title`, `description`, `canonical`, `robots`, `openGraph`, `links`, `jsonLd`, and an `html` object for `lang`/`dir` — the fields that end up in `<head>` or on the document element. For a page whose metadata never changes, just pass the object directly as `RouteOptions.meta` or `PageHelperOptions.meta`; there's also a plain `title` shorthand on `RouteOptions` for the common case where only the tab title matters.

Dynamic metadata

`RouteMetaSource` is `RouteMeta | ((context) => RouteMeta | PromiseLike<RouteMeta>)`, so metadata can be computed from the resolved `RouteContext` — pulling a post title out of loader data, for instance — and it can be async if that computation needs to await something. Metadata sources stack: a route's `metaChain` collects sources from outermost group down to the specific route, and `resolveRouteMeta(record, context)` merges them in that order into the final `RouteMeta` used for the response or the client update.

Head reconciliation

After a client-side navigation, `reconcileRouteMeta(meta, target?)` updates only the `<head>` nodes Askr owns — replacing the title, meta tags, and links from the previous route with the new ones — without touching tags injected by other scripts or the initial HTML shell. That scoping matters for SPA navigations specifically: a full page load already gets the right head from SSR/SSG output, so reconciliation only runs on the client-side transition path.

SSG metadata

For statically generated routes, `RouteOptions.entries` returns the list of param combinations to pre-render, and metadata for each generated page resolves the same way it would for SSR — through the route's `metaChain` and `resolveRouteMeta()` — so a dynamic `RouteMeta` function keyed on `params.slug` produces correct per-page titles and descriptions across every entry. `serializeRouteMeta(meta)` turns the resolved `RouteMeta` into the actual head markup written into each generated HTML file.