Navigation
StateMesh provides declarative navigation via <Link> and programmatic navigation via useNavigate. Route params and search params are accessible via useParams and useSearch.
Link Component
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>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Link Props
| Prop | Type | Description |
|---|---|---|
to | string | Target path pattern |
params | Record<string, string> | Path parameters |
search | Record<string, unknown> | Query parameters |
replace | boolean | Use replaceState instead of pushState |
preload | boolean | Preload the route on hover/focus |
activeClass | string | CSS class when the route is active |
className | string | Base 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>
);
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Navigate Options
ts
navigate("/products/:id", {
params: { id: "kbd" },
search: { ref: "home" },
replace: true // Use replaceState
});1
2
3
4
5
2
3
4
5
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>;
}1
2
3
4
5
6
2
3
4
5
6
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>
);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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>
);
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
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
- Guards & Middleware — Route protection
- Data Loading — Loaders and error recovery
- Routes — Route definitions
