Navigation
The core rule everywhere in this API:
Routes without required params accept a plain string. Routes with required params require a typed
paramsobject. Both are autocompleted.
<Link>
A typed drop-in for the router's Link — same props, except to is the union of your route paths
and params / searchParams / hash are added:
Param values may be string | number — they're stringified into the URL.
<Navigate>
Typed drop-in for declarative redirects:
useNavigate()
Returns an object of navigation helpers (not a bare function):
navigateTo(path, options?)
Options: params (required iff the route has required params), searchParams, hash,
replace, state.
createUrl(path, options?)
Builds the URL string without navigating — for window.open, sharing, analytics:
goBack()
Equivalent to originalNavigate(-1).
originalNavigate
The untouched React Router navigate — the escape hatch for anything the typed API doesn't cover
(relative navigation, navigate(-2), external logic):
buildPath(path, options?)
The pure, hook-free version of createUrl — usable in data loaders, tests, or outside React:
useTypedParams(path)
Reads the current route's params, typed by the route you're in. Read-side values are always
string (that's what the URL contains):
Accepting route paths in your own components
Use the exported unions to type your own props (e.g. breadcrumbs, menus). The
RoutePathname | (string & {}) trick keeps autocomplete while still allowing arbitrary strings:
Everything else from the router
The package re-exports the full @modern-js/runtime/router surface (Outlet, useParams,
useLocation, useSearchParams, useLoaderData, redirect, isRouteErrorResponse, …), so your
app can use a single import source:
Add a lint rule banning direct @modern-js/runtime/router imports so typed navigation is the only
path. With Biome: noRestrictedImports on @modern-js/runtime/router pointing users to
modernjs-typed-routes.