API reference
resolveFilterParams
Compute the hook's params object outside React, for route loaders.
resolveFilterParams(configs, rawSearch, options?) => params
resolveFilterParams<P>(configs, rawSearch, options?) => params // validate against an API typeThe framework-agnostic twin of the hook's params derivation. Runs anywhere
(route loaders, server code) and produces the identical object useFilters
computes on mount, so a prefetch hits the same cache key. See
Route loaders.
configs— the same config map you pass to the hook.rawSearch— the request's search params, in any of these shapes:- a parsed object (
{ status: 'open' }), - a
URLSearchParams(new URL(request.url).searchParams), - the raw query string (
'?status=open'orlocation.search).
- a parsed object (
options—{ arraySeparator, pagination }. These must match the hook's for the query keys to align;defineFiltersbinds them once to remove that risk.
Behavior
- Applies each filter's
defaultValue(ornull) exactly like the hook. - Coerces values to the same types (
?status=5→ the number5, not'5'). - Mirrors the pagination keys into the result under the configured names.
- Drops extras such as async
_labelsidecars.
const params = resolveFilterParams(productConfigs, new URL(request.url).searchParams);
// => { search, status, page, per_page } — same shape as useFilters' paramsPassing <P> validates configs against your API's params type and types the
result as exactly P — the same
contract useFilters<P> enforces (required keys
declared, non-null params defaulted):
const params = resolveFilterParams<ProductListParams>(productConfigs, request.url);
// params: ProductListParams — soundlyChoice filters (select / multiSelect) require
valueType for exactly this reason — the loader never
sees options, so a value type inferred from them would risk disagreeing with the hook.
valueType is a static declaration both sides read the same way.