Search Params
Bind React state to URL search params in the Next.js app router.
useSearchParams binds state to URL search params. The URL is the single
source of truth: refreshing, sharing, or bookmarking the link restores the
exact state. Writes use the native History API by default (shallow), so
no server round-trip happens, and updates are applied optimistically
inside a React transition.
import { } from 'kvantjs/next'
import * as from 'kvantjs/schema'
function () {
const [, ] = ('q', .().(''))
return (
<
={}
={ => (..)}
/>
)
}Setting a key to undefined removes its entry. Values equal to the
schema default are never written. Defaults stay internal.
Multiple hooks bound to the same key stay in sync automatically.
Key maps work too:
const [, ] = ({
: .().(''),
: .().(0),
: .(['asc', 'desc']).('asc'),
: .(.()).([]), // repeated params: ?tags=a&tags=b
})
( => ({ ..., : . + 1 }))Fast-changing values
kvant does not yet provide built-in throttle/debounce for URL writes. Until then, avoid binding state directly to quickly changing values (text inputs, sliders), or wrap the binding in a throttled layer with local state:
import { useThrottleFn } from 'react-use'
function SearchInput() {
const [search, setSearch] = useSearchParams('q', kv.string().default(''))
// Local state updates instantly; the URL follows at most every 300 ms
const [text, setText] = useState(search)
useThrottleFn(setSearch, 300, [text])
return <input value={text} onChange={e => setText(e.target.value)} />
}Options
Prop
Type
Set options once for a component subtree using the options provider:
import { } from 'kvantjs/next'
< ={{ : 'push' }}>
{}
</>Custom search serializer
The default serializer uses URLSearchParams, so values are flat strings
(or repeated keys for arrays). For nested structures, plug in a custom
parser/serializer, for example qs, by
defining your own binding (see Advanced Usage):
'use client'
import { } from 'kvantjs/next'
import { } from 'kvantjs/react'
import qs from 'qs'
export const {
: ,
:
} = (
(, ) => (, {
: => qs.(, { : true }),
: => qs.(, { : true }),
...,
}),
)With qs handling (de)serialization, the full power of kvantjs/schema
opens up inside the URL: objects, nested arrays, and more.
const [, ] = (
'filters',
.({
: .(.()).([]),
: .([.(), .()]).(),
}).({}),
)
// URL: ?filters[tags][0]=a&filters[tags][1]=b&filters[range][0]=1&filters[range][1]=9