Skip to content
This repository has been archived by the owner on Feb 14, 2025. It is now read-only.
/ sp-hooks Public archive

Use search params as a state in your web application.

License

Notifications You must be signed in to change notification settings

bring-shrubbery/sp-hooks

Repository files navigation

Search Params Hooks

build

Features

  • 😌 Easily sync state to the URL Search Params and back again.
  • 💪 Use your own state manager.
  • 🤓 Keeps URL clean by automatically removing default values.
  • 😳 React Server Components ready.
  • 🚀 Next.js integration.
  • 🤯 Full TypeScript support.
  • 😇 Integrations for SvelteKit/Solid.js coming soon.
  • ⚡️ Accepts Zod schema for validation and parsing (WIP).

Packages

Package Latest Version
@usps-hooks/react react-npm
@usps-hooks/next next-npm

Getting Started

Step 1 ⭐️

Before we start, don't forget to star this repo and follow @bring-shrubbery, thanks!

Next.js

pnpm add @sp-hooks/next

React.js

pnpm add @sp-hooks/react

Examples

Simple Next.js usage

Following example will render a button, which when clicked will toggle the button text between "hello" and "world". It will also update the search params to include the value, which means that after refreshing the page, the state will be preserved.

import { useState } from "react";

import { useObserveAndStore } from "@sp-hooks/next";

const Component = () => {
  const [state, setState] = useState({ greeting: "hello" });

  useObserveAndStore(state);

  const handleClick = () => {
    const greeting = state.greeting === "hello" ? "world" : "hello";

    setState({ greeting });
  };

  return <button onClick={handleClick}>{state.greeting}</button>;
};

Next.js usage with default values

This example works in the same way functionally speaking. In the example above you can see that we manually fall back on the default text value for ths button, but there's a better way. You can provide defaultValues parameter to the useSearchParamsState hook as seen below. This will do 3 things:

  • If no search params are provided, the greeting parameter will fall back the default value.
  • When greeting search param is set to the default value, that value will be removed from the URL, since your code will automatically fallback to that value (You can disable this behavior in options, read more here).
  • TypeScript will understand that you have greeting parameter available, and will autosuggest it for you.
import { useSearchParamsState } from "@sp-hooks/next";

const Component = () => {
  const [state, setState] = useSearchParamsState({
    defaultValues: {
      greeting: "hello",
    },
  });

  const handleClick = () => {
    state.greeting === "hello"
      ? setState("greeting", "world")
      : setState("greeting", "hello");
  };

  return <button onClick={handleClick}>{state.greeting}</button>;
};

Next.js with Zod validation (coming soon)

Here, before using the search params hook, we define Zod validation schema that we want to use for the search params validation. Then we only need to pass the schema into the zodSchema prop inside of our useSearchParamsState, and we're good to go! Now our state is fully type-safe, and if we define schema with .catch statements, then it even catches invalid values and falls back to default ones! Additionally, you get number types automatically by using z.coerce to parse numbers.

"use client"
import { useSearchParamsState } from "@sp-hooks/next";
import { z } from 'zod'

const SearchParamsSchema = z.object({
  page: z.coerce.number().catch(1),
  perPage: z.coerce.number().catch(100),
  search: z.string().optional(),
})

const Component = () => {
  const [state, setState] = useSearchParamsState({
    zodSchema: SearchParamsSchema
  });

  return <>
    ...
  </>;
};

// In a `page.tsx`:

export default function Page({ searchParam }) {
  const parsedParams = SearchParamsSchema.parse(searchParams);

  const data = db.query(..., {
    page: parsedParams.page,
    perPage: parsedParams.perPage,
    search: parsedParams.search,
  });

  return <Component data={data}/>
}

Roadmap

  • State comes from search params.
  • Set state updates search params.
  • Default values.
  • Option to remove search params if they are set to their default values.
  • Remove falsy values.
  • Preserve initial keys - keys are preserved in search params, if they were initially set.
  • Next.js integration.
  • Array values.
  • Zod validation.
  • Zod default values.
  • Zod optional values.
  • Type-safe state from default values or when validation schema is provided.
  • More validation tools (yup, etc.).
  • Svelte/SvelteKit

Credits

This project is built and maintained by Antoni

If you need help building anything that has a frontend, check out Quassum

License

Apache 2.0 License