# useSearchParam

One URL query parameter (`?tab=billing`) as state: its value, or `null` when it's missing, and a setter that updates the URL without reloading. Works with or without a router: re-renders on `set` (in any component), Back and Forward, and router navigation that uses `history.pushState` (in browsers with the Navigation API).

The server render and hydration use `serverValue`, then the real URL with no hydration mismatch. Pass the request's value (e.g. from `searchParams` in a Next.js page) so the first frame is already right.

Works with Next.js's App Router: after `set`, Next's own `useSearchParams` updates too, and no server request is made.

## Import

```ts
import { useSearchParam } from '@vincent.ri/react-tils'
// or only this hook
import { useSearchParam } from '@vincent.ri/react-tils/useSearchParam'
```

## Usage

```ts
const [query, setQuery] = useSearchParam('q')
return <input value={query ?? ''} onChange={(e) => setQuery(e.target.value || null)} />

// Tabs where Back returns to the previous tab
const [tab, setTab] = useSearchParam('tab')
return <button onClick={() => setTab('billing', { push: true })}>Billing</button>
```

## When to use it

State that should be linkable, bookmarkable, and survive reload: the selected tab, a search query, filters, sorting, a page number, an open item's id.

## When not to

Your router already gives you this (React Router's `useSearchParams`); for state that shouldn't reach the server, use `useHash`; for private or large state, use `useLocalStorage`. Values are strings: parse numbers and validate, since anyone can edit the URL.

## API

```ts
function useSearchParam(name: string, serverValue?: string | null): [string | null, (value: string | null, options?: {
  push?: boolean;
}) => void]
```

| Parameter | Description |
| --- | --- |
| `name` | The parameter name. |
| `serverValue` | The value on the server and during hydration. Default `null`. |

**Returns** `[value, set]`. `set(value)` replaces the current history entry; `set(value, { push: true })` adds one, so Back undoes it. `set(null)` removes the parameter.

## Browser support

Works in all modern browsers.

- Router navigation that changes the URL with `history.pushState` (e.g. Next.js `<Link>`) is noticed only where the Navigation API exists. Elsewhere the value still updates on Back and Forward and through the hook's own setter.

## Coming from another library?

Other libraries call this `useQueryState` (nuqs), `useSearchParam` (react-use), `useUrlState`.

---

310 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useSearchParam.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useSearchParam/
Previous: [useHash](https://vincentri.github.io/react-tils/hooks/useHash.md)
Next: [useBroadcastChannel](https://vincentri.github.io/react-tils/hooks/useBroadcastChannel.md)
