Runtime API
Everything below is imported from the package root:
Components
Link<P extends RoutePath>
All props of the router's Link except to, plus:
Navigate<P extends RoutePath>
Same typing as Link over the router's Navigate (replace, state, … pass through).
Hooks
useNavigate()
Returns NavigateHelpers:
NavigateToOptions<P> = BuildOptions<P> & { replace?: boolean; state?: unknown }.
BuildOptions<P> = { params: RouteParams<P>; searchParams?; hash? } with params conditionally
required/optional depending on the route.
The rest-tuple (NavigateArgs<P> / BuildArgs<P>) is what makes the options object itself
required exactly when the route has required params — navigateTo('/blog/[id]') is a type error,
navigateTo('/about') is not:
Only relevant if you build a library on top of this one (declaration: true, and your own
package has no generated routes). Returning a helper with an inferred type makes TypeScript
synthesize the signature when it writes your .d.ts, and synthesizing flattens the rest-tuple —
your consumers lose the conditional params requirement.
Annotate the return type with the exported types and the conditional survives:
Apps (which generate routes, so Register is populated) are unaffected — and re-exporting
useNavigate, Link or buildPath directly is always safe.
useTypedParams(path)
Functions
buildPath(path, options?)
Pure URL builder (no hooks — safe in loaders, tests, Node):
Behavior details:
- Param values are URL-encoded; splat (
'*') values keep their/separators (each piece is encoded individually; leading slashes are normalized away). - An absent optional param (
[id$]) or splat drops its segment cleanly — no//is ever produced.''counts as absent (substituting it would build an unmatchable URL). - A missing (or empty-string) required param throws (naming the param and the path) instead of emitting a broken URL — types prevent this in TS; plain-JS consumers fail fast at the call site.
- With several optional segments in one path, omitting an EARLIER one while providing a later one builds a shorter URL the router matches against the first optional slot — provide optionals left-to-right.
buildPathis basename-unaware (it's pure — no router context). Multi-entry keys already carry their mount prefix, so their built URLs are real URLs; but a customruntime.router.basenameis NOT prepended — inside components, usecreateUrl(which reads the active basename) when you need the full browser URL.
Types
Entry-scoped types (multi-entry apps)
Use these to keep one entry's routes out of another's autocomplete — see Multi-entry apps.
Re-exports
The full @modern-js/runtime/router surface is re-exported (Outlet, useParams, useLocation,
useSearchParams, useLoaderData, useMatches, redirect, defer, isRouteErrorResponse,
NavLink, …). Our typed Link, Navigate and useNavigate shadow the originals; reach the raw
versions via originalNavigate or a direct @modern-js/runtime/router import if you truly need them.