URL State
URL state syncs mesh state to browser URL query parameters. Changes to state update the URL; browser back/forward and direct URL changes update state.
Define URL State
mesh.urlState("products.filters", {
search: "",
category: "all",
page: 1,
sort: "latest"
}, {
paramNames: {
search: "q",
category: "cat",
page: "p"
}
});Use in React
import { useMeshUrlState } from "statemesh-core";
function ProductFilters() {
const [filters, setFilters] = useMeshUrlState<{
search: string;
category: string;
page: number;
sort: string;
}>("products.filters");
return (
<div>
<input
value={filters.search}
onChange={(e) => setFilters({ search: e.target.value, page: 1 })}
/>
<select
value={filters.category}
onChange={(e) => setFilters({ category: e.target.value })}
>
<option value="all">All</option>
<option value="electronics">Electronics</option>
</select>
</div>
);
}This reads and writes URLs like:
/products?q=keyboard&cat=electronics&p=1&sort=latestCustom Param Names
Use paramNames to map state fields to URL-friendly parameter names:
mesh.urlState("filters", {
search: "",
page: 1,
sale: false
}, {
paramNames: {
search: "q",
page: "p",
sale: "available"
}
});URL: /products?q=keyboard&p=2&available=true
Resolver Function
For fully custom naming, use a resolver function:
mesh.urlState("filters", defaults, {
paramNames: (field) => `filter_${field}`
});paramNames takes priority over paramPrefix; unmapped fields fall back to paramPrefix or the field name.
Capture Unknown Params
Dynamic query params can be captured into one object field:
mesh.urlState("products.filters", {
search: "",
params: {} as Record<string, string>
}, {
paramNames: {
search: "q"
},
captureUnknown: /^filter_/,
unknownField: "params"
});URL: /products?q=keyboard&filter_brand=keychron Result: { search: "keyboard", params: { filter_brand: "keychron" } }
Options
| Option | Type | Description |
|---|---|---|
paramNames | Record<string, string> | (field) => string | Map state fields to URL param names |
paramPrefix | string | Prefix for all params (fallback) |
captureUnknown | RegExp | Capture unknown params matching this pattern |
unknownField | string | Field to store captured unknown params |
replace | boolean | Use replaceState instead of pushState |
debounce | number | Debounce URL updates in ms |
History Adapters
import { createBrowserHistory, createMemoryHistory } from "statemesh-core/router";
// Browser history (default)
const browserHistory = createBrowserHistory("/app");
// Memory history (for testing and SSR)
const memoryHistory = createMemoryHistory("/", ["/products", "/products/kbd"]);SSR Safety
URL state is SSR-guarded. In server environments (where window is undefined), the URL state is registered but no browser APIs are accessed.
Important Notes
TIP
URL state is SSR-safe. All browser API access is guarded with isBrowser() checks.
WARNING
Setting replace: true prevents the browser back button from capturing every filter change. Use it for high-frequency updates like search input.
TIP
Use paramNames when the URL should use API/product-friendly names instead of state field names.
Next Steps
- Forms — Form state management
- Error Boundaries — Suspense error handling
- Router — Built-in router
