Skip to content

Type-safe navigation

Declaring routes as const gives the router compile-time path templates. navigate (and the adapters' useNavigate) then only accept paths your routes actually define — typos and stale links become type errors, not runtime 404s.

Hover the code

The examples on this page are powered by Twoslash — hover any identifier to see its inferred type, exactly as your editor would.

Known paths only

ts
import { 
createCoreRouter
} from "@isorouter/core";
const
router
=
createCoreRouter
([
{
path
: "/" },
{
path
: "/concerts/:city" },
{
path
: "/users/:id" },
] as
const
);
router
.
navigate
("/concerts/kyiv"); // ok
router
.
navigate
("/concerts/kyiv?from=search"); // ok — optional ?query
router
.
navigate
("/users/42#bio"); // ok — optional #hash
router
.
navigate
("/no-such-route"); // type error
Argument of type '"/no-such-route"' is not assignable to parameter of type 'NavTarget<readonly [{ readonly path: "/"; }, { readonly path: "/concerts/:city"; }, { readonly path: "/users/:id"; }]>'.

The param segment "/concerts/:city" becomes the template `/concerts/${string}`, so any city value type-checks while the shape is enforced. An optional ?query and/or #hash may be appended to any known path.

Extracting param types

ExtractParams resolves a path template to its params object — handy for typing params you read elsewhere:

ts
import type { 
ExtractParams
} from "@isorouter/core";
type
Params
=
ExtractParams
<"/concerts/:city">;

With the adapters

useNavigate() carries the same path types through. Declare routes as const, and the returned function rejects unknown paths:

tsx
import { useNavigate } from "@isorouter/react";

function Search() {
  const navigate = useNavigate();
  // navigate("/concerts/kyiv") ✓   navigate("/nope") ✗ (type error)
  return <button onClick={() => navigate("/concerts/kyiv")}>Go</button>;
}
ts
import { useNavigate } from "@isorouter/vue";

const navigate = useNavigate();
// navigate("/concerts/kyiv") ✓   navigate("/nope") ✗ (type error)
navigate("/concerts/kyiv");
svelte
<script lang="ts">
  import { getRouter } from "@isorouter/svelte";
  const router = getRouter();
  // router.navigate("/concerts/kyiv") ✓   router.navigate("/nope") ✗
</script>

navigate takes an optional second argument:

ts
router
.
navigate
("/concerts/kyiv", {
replace
: true, // replace the current history entry instead of pushing
state
: {
from
: "search" }, // attach state to the navigation entry
});

Released under the MIT License.