Skip to content

Navigation

StateMesh provides declarative navigation via <Link> and programmatic navigation via useNavigate. Route params and search params are accessible via useParams and useSearch.

tsx
import { Link } from "statemesh-core/router";

// Basic link
<Link to="/products">Products</Link>

// With params
<Link to="/products/:id" params={{ id: "kbd" }}>Keyboard</Link>

// With search params
<Link to="/search" search={{ q: "mouse" }}>Search mice</Link>

// Preload on hover
<Link to="/products" preload>Products (preload)</Link>

// Active class
<Link to="/products" activeClass="active">Products</Link>
PropTypeDescription
tostringTarget path pattern
paramsRecord<string, string>Path parameters
searchRecord<string, unknown>Query parameters
replacebooleanUse replaceState instead of pushState
preloadbooleanPreload the route on hover/focus
activeClassstringCSS class when the route is active
classNamestringBase CSS class

useNavigate

Programmatic navigation:

tsx
import { useNavigate } from "statemesh-core/router";

function ProductCard({ product }: { product: Product }) {
  const navigate = useNavigate();

  return (
    <button onClick={() => navigate("/products/:id", { params: { id: product.id } })}>
      View product
    </button>
  );
}
ts
navigate("/products/:id", {
  params: { id: "kbd" },
  search: { ref: "home" },
  replace: true  // Use replaceState
});

useParams

Read the current route's path parameters:

tsx
import { useParams } from "statemesh-core/router";

function ProductDetail() {
  const { id } = useParams<{ id: string }>();
  return <h1>Product {id}</h1>;
}

useSearch

Read and update the current route's search parameters:

tsx
import { useSearch } from "statemesh-core/router";

function SearchPage() {
  const [search, setSearch] = useSearch<{ q: string; page: number }>();

  return (
    <div>
      <input
        value={search.q}
        onChange={(e) => setSearch({ q: e.target.value, page: 1 })}
      />
      <p>Page: {search.page}</p>
    </div>
  );
}

useMatch

Read the full route match including params, search, loader data, and error state:

tsx
import { useMatch } from "statemesh-core/router";

function CurrentRoute() {
  const match = useMatch();
  return (
    <div>
      <p>Path: {match.fullPath}</p>
      <p>Params: {JSON.stringify(match.params)}</p>
      <p>Data: {JSON.stringify(match.data)}</p>
    </div>
  );
}

Important Notes

TIP

<Link> uses the router's history adapter. It doesn't cause a full page reload — navigation is client-side.

TIP

Use preload: "intent" in router options to automatically preload routes on hover/focus. This makes navigation feel instant.

Next Steps

Released under the MIT License.