Skip to main content
Version: Next (Unreleased)

useQueryParams

Read and write URL query parameters with full type safety. Automatically stays in sync with browser navigation (back / forward).

Signature

function useQueryParams<TQuery extends Record<string, any>>(): {
get: (...keys: (keyof TQuery)[]) => Partial<TQuery>;
set: (params: Partial<TQuery>, url?: string) => void;
build: (params: Partial<TQuery>) => string;
pathname: string;
search: string;
clear: () => void;
}

Type parameter

Define your query shape as a generic for auto-completion and type-safe access:

interface Filters {
page: number;
q: string;
active: boolean;
}

const { get, set } = useQueryParams<Filters>();
const { page, q } = get("page", "q");
set({ page: 2 });

Return value

Method / PropertyDescription
get(...keys)Returns an object with the requested params, auto-casting to boolean, number, or parsed JSON
set(params, url?)Pushes updated params to the URL. Optionally target a different path
build(params)Returns a query string from params without navigating
pathnameCurrent location.pathname
searchCurrent location.search
clear()Removes all query params from the URL

Value auto-casting

get() automatically casts values from the URL string:

String valueCasted as
"true" / "false"boolean
"42"number
'{"a":1}'Parsed object/array
Anything elsestring

Example

import { useQueryParams } from "@julianfere/hooked";

interface SearchParams {
q: string;
page: number;
active: boolean;
}

function SearchPage() {
const { get, set, clear } = useQueryParams<SearchParams>();
const { q = "", page = 1 } = get("q", "page");

return (
<div>
<input value={q} onChange={(e) => set({ q: e.target.value, page: 1 })} />
<button onClick={() => set({ page: page + 1 })}>Next page</button>
<button onClick={clear}>Clear filters</button>
</div>
);
}
note

This hook relies on window.location and history.pushState. It is not compatible with server-side rendering out of the box.