Skip to content
Ilha
Esc
↑↓navigate↵open⌘Jpreview
On this page

Router reference

Public exports from @ilha/router.

See Router overview for a guided tour.

@ilha/router

Router

router(options?: RouterOptions): RouterBuilder
Router option Meaning
mode "spa" (default) or "static" (registry only)
notFound Component for unmatched paths
interceptLinks Intercept same-origin <a> clicks (default true)
viewTransitions Wrap navigations in the View Transition API
allowExternalRedirects Allow cross-origin redirects (default false)

Builder

Method Purpose
route(pattern, page) Register a URL pattern
errorBoundary(pattern, handler) Catch failures for a pattern
mount(target, { hydrate?, interceptLinks? }) Activate in the browser
render(url) HTML string
renderResponse(url) { kind, html / to, status, head }
respond(url) Response with security headers

Render results are discriminated: { kind: "html" }, { kind: "redirect", to, status }, or { kind: "error", status, html, message }.

Route context

Export Meaning
useRoute() { path, params, search, hash, navigating } accessors
routePath() / routeParams() / routeSearch() / routeHash() Standalone accessors
searchParam(name, { default, parse?, serialize? }) Read and replace-write one query param without remounting
navigating() True while a navigation is in flight
navigate(to, { replace?, scroll? }) Programmatic navigation
isActive(href) True when the current path matches
beforeNavigate(fn) Hook before every navigation; call cancel() to stop it. Returns an unsubscribe function
afterNavigate(fn) Hook after every navigation. Returns an unsubscribe function
prime() Sync route state from the address bar without mounting
useContext() { request } for the current render, if the server scoped one
setHistoryMode(mode) "history" (default) or "hash"

The mounted router intercepts same-origin <a> clicks. You opt a link out with a bare data-no-intercept attribute.

head(
  title?: string;
  titleTemplate?: string | ((title?: string) => string);
  meta?: Array<Record<string, string>>;
  link?: Array<Record<string, string>>;
  script?: Array<Record<string, string> & { children?: string }>;
});

Call inside a page or layout. Layouts typically set titleTemplate; pages set title. Works during SSR and on the client (mutates document.head / document.title).

The head window stays live for the whole client mount: a page that fetches first and calls head() after await still updates document. There are no loaders and no route guards — fetch in an async page, and confirm or cancel through beforeNavigate().

Pages and errors

Export Purpose
wrapLayout(layout, page) Wrap a page in a layout (children carries it)
wrapError(handler, page) Catch page throws, render a fallback view
defineLayout(layout) Type helper for layout components
redirect(to, status?) / error(status, message) Throw Redirect / RouteError
httpResponse(html, { status?, headers?, cspNonce?, contentSecurityPolicy? }) Headered Response

AppError is { message, status?, stack? }. See Error boundaries.

@ilha/router/vite and /rsbuild

pages(options?) — file-system routing plugin. Default dir src/pages, out .ilha.

Option Meaning
dir Pages directory
outDir Generated modules directory
mode "spa" or "static"
frameGuard Dev frame guard
trustedOrigins Explicit origins for frame checks
csrf Optional CSRF verifier for frame POSTs

Virtual modules: ilha:pages/client, ilha:pages/server — see File-system routing.

@ilha/router/ssr

Production middleware for POST /__ilha/frame.

Export Purpose
ssr (default) The fetch handler itself
setFrameAuth defaultAction, trustedOrigins, csrf
setFrameGuard Per-request allow/deny
renderServerIsland(id, request, runWithScope, props?) Render one server island — returns Effect<string, FrameError>. Use renderServerIslandResult for a plain Promise

@ilha/router/server-island

Generated client proxies. You do not import this in app code.

Was this page helpful?