Skip to content

useSearchParams

React hook to extract search parameters from URL.

Add the hook via the CLI:

sh
npx @novajslabs/cli add useSearchParams
sh
npx @novajslabs/cli add useSearchParams
sh
pnpm dlx @novajslabs/cli add useSearchParams

Or copy and paste the code into your project:

ts
import { useEffect, useState } from "react";

/* eslint-disable-next-line */
type TUseSearchParams = <T = Record<string, any>>(
  url?: string,
  opt?: { unique: boolean }
) => T;

export const useSearchParams: TUseSearchParams = <T>(
  url = location.href,
  opt = { unique: true }
) => {
  const _urlSearch = new URL(url);
  const [params, setParams] = useState<Record<string, string | string[]>>(() =>
    Object.fromEntries(_urlSearch.searchParams.entries())
  );

  useEffect(() => {
    const len: number = Object.values(params).length;

    if (!opt || opt.unique || len === _urlSearch.searchParams?.size) return;

    for (const [key, value] of _urlSearch.searchParams) {
      if (value === params?.[key]) continue;
      if (
        Array.isArray(params?.[key]) &&
        Array.from(params?.[key]).includes(value)
      )
        continue;
      setParams(() => ({
        ...params,
        [key]: [...(params?.[key] ?? []), value],
      }));
    }
  }, []);

  return Object.fromEntries(
    Object.entries(params).map(([key, value]) => [
      key,
      !Array.isArray(value)
        ? JSON.parse(value)
        : value.map((items) => JSON.parse(items)),
    ])
  ) as T;
};
js
import { useEffect, useState } from "react";

export const useSearchParams = (
  url = location.href,
  opt = { unique: true }
) => {
  const _urlSearch = new URL(url);
  const [params, setParams] = useState(() =>
    Object.fromEntries(_urlSearch.searchParams.entries())
  );

  useEffect(() => {
    const len = Object.values(params).length;

    if (!opt || opt.unique || len === _urlSearch.searchParams?.size) return;

    for (const [key, value] of _urlSearch.searchParams) {
      if (value === params?.[key]) continue;
      if (
        Array.isArray(params?.[key]) &&
        Array.from(params?.[key]).includes(value)
      )
        continue;
      setParams(() => ({
        ...params,
        [key]: [...(params?.[key] ?? []), value],
      }));
    }
  }, []);

  return Object.fromEntries(
    Object.entries(params).map(([key, value]) => [
      key,
      !Array.isArray(value)
        ? JSON.parse(value)
        : value.map((items) => JSON.parse(items)),
    ])
  );
};

Requirements

React 16.8 or higher

Parameters

url

Type: string

The URL to parse the search parameters from. Defaults to the current window location.

opt

Type: object

Options for parsing parameters.

opt.unique

Type: boolean

If true, ensures each parameter key has a unique value. Defaults to true.

Return values

params

Type: T

An object containing the parsed search parameters. Values are parsed as JSON, supporting both single and multiple values.

Example

tsx
import { useSearchParams } from "./hooks/useSearchParams";

const App = () => {
  const searchParams = useSearchParams();

  return (
    <div>
      <h1>Search Results</h1>
      <pre>{JSON.stringify(searchParams, null, 2)}</pre>
    </div>
  );
};

export default App;

Use cases

Here are some use cases where this React hook is useful:

  • Extracting filters from a URL in a product listing page
  • Reading query parameters for user authentication or redirection
  • Parsing search inputs for a blog or article listing
  • Managing URL state for multi-step forms
  • Extracting parameters for API requests in a dashboard