nuqs

repository·next·Indexed 27 days ago

https://github.com/47ng/nuqs

A type-safe search params state manager for React frameworks that allows developers to manage URL query strings using a hook-based API similar to useState. It provides adapters for Next.js (app and pages routers), Remix, React Router (v6, v7, v8), TanStack Router, and plain React SPAs.

Tokens
40.2K
Snippets
125
Records
195
Agent score
94%

What's inside nuqs

  1. Understand the Release Pipeline Ubiquitous Language

    next
    The nuqs release pipeline uses a specific set of canonical terms to ensure that version computation (bumps), release notes (changelogs), and finalization are always in sync. The core invariant is that a change's type and breaking flag (both immutable and derived from the commit) are the single sources of truth for the changelog category and the version bump.
  2. Configure nuqs in Monorepo setups

    next

    When using nuqs in a monorepo where components reside in shared or workspace packages:

    1. Ensure all components using nuqs are rendered within the tree below the application's NuqsAdapter.
    2. Ensure all packages use the same version of nuqs to avoid context mismatches.
  3. Test hooks with React Testing Library

    next

    When testing hooks that use useQueryState, use withNuqsTestingAdapter from nuqs/adapters/testing as a wrapper in the React Testing Library renderHook function. This allows you to provide initial search parameters for the hook to consume.

    import { withNuqsTestingAdapter } from 'nuqs/adapters/testing'
    
    const { result } = renderHook(() => useTheHookToTest(), {
      wrapper: withNuqsTestingAdapter({
        searchParams: { count: "42" },
      }),
    })
  4. Implement a three-phase staged publishing workflow

    next

    To harden the release pipeline against supply-chain attacks and avoid coupling documentation deployment with package publishing, implement a three-phase workflow:

    1. Draft Phase (Manual via workflow_dispatch):

      • Compute the new version by walking the commit tree (e.g., using conventional commits).
      • Run npm stage publish with provenance (OIDC).
      • Create a draft GitHub release with formatted release notes.
    2. Validation Phase (Maintainer Review):

      • Inspect the staged tarball to ensure the build is legitimate and reproducible.
      • If the release is invalid, discard the draft GitHub release and reject the staged npm package.
    3. Finalize Phase (Manual):

      • Approve the staged npm package using 2FA to move it to the live registry.
      • Publish the GitHub release (which creates the Git tag).
  5. Configure SEO canonical URLs for query string state

    next

    If your page uses query strings for local-only state, use a canonical URL in your metadata to tell crawlers to ignore the query string.

    If the query string defines the content (e.g., a video ID), use createLoader, createSerializer, and urlKeys from nuqs/server to generate a canonical URL that includes the necessary parameters.

    import type { Metadata } from 'next'
    import { 
      createParser, 
      parseAsString, 
      createLoader, 
      createSerializer, 
      type UrlKeys 
    } from 'nuqs/server'
    
    const youTubeSearchParams = {
      videoId: createParser({
        parse: (q) => (/^[^"&?\/\s]{11}$/i.test(q) ? q : null),
        serialize: (v) => v
      })
    }
    const youTubeUrlKeys: UrlKeys<typeof youTubeSearchParams> = { videoId: 'v' }
    const loadYouTubeSearchParams = createLoader(youTubeSearchParams, { urlKeys: youTubeUrlKeys })
    const serializeYouTubeSearchParams = createSerializer(youTubeSearchParams, { urlKeys: youTubeUrlKeys })
    
    export async function generateMetadata({ searchParams }) {
      const { videoId } = await loadYouTubeSearchParams(searchParams)
      return {
        alternates: {
          canonical: serializeYouTubeSearchParams('/watch', { videoId })
        }
      }
    }
  6. Integrate nuqs with TanStack Router using validateSearch

    next

    To use nuqs search params with TanStack Router's validateSearch, use createStandardSchemaV1.

    Important: Because nuqs and TanStack Router have different default strategies, you must set the partialOutput: true option in createStandardSchemaV1 to ensure the resulting search params are treated as optional in TanStack Router.

    Note: TanStack Router support is experimental.

    import { createStandardSchemaV1 } from 'nuqs'
    
    // Use partialOutput: true to keep values optional for TanStack Router
    const validateSearch = createStandardSchemaV1(searchParams, {
      partialOutput: true
    })
    
    export const Route = createFileRoute('/search')({
      validateSearch
    })
  7. Setup Nuqs with Next.js App Router

    next

    To use nuqs in a Next.js App Router project, wrap your root layout's {children} with the NuqsAdapter from nuqs/adapters/next/app.

    import { NuqsAdapter } from 'nuqs/adapters/next/app'
    import { type ReactNode }
    
    export default function RootLayout({
      children
    }: {
      children: ReactNode
    }) {
      return (
        <html >
          <body>
            <NuqsAdapter>{children}</NuqsAdapter>
          </body>
        </html>
      )
    }
  8. Use React Transitions with query updates

    next

    When using shallow: false in Next.js, you can integrate React's useTransition hook to provide loading states while the server re-renders components with the updated URL. Pass the startTransition function into the parser's options.

    'use client'
    
    import React from 'react'
    import { useQueryState, parseAsString } from 'nuqs'
    
    function ClientComponent() {
      const [isLoading, startTransition] = React.useTransition()
      const [query, setQuery] = useQueryState(
        'query',
        parseAsString.withOptions({
          startTransition,
          shallow: false
        })
      )
    
      if (isLoading) return <div>Loading...</div>
      return <div>{query}</div>
    }
  9. Enable debug logs in Node.js (SSR/RSC)

    next

    To enable debug logs in Node.js environments (such as SSR, React Server Components, or when using nuqs/server), import nuqs/debug from a server entry point (e.g., a Next.js root layout).

    Enable logging by setting the DEBUG environment variable to include nuqs. This can be done via the command line, a .env file, or your hosting provider's configuration. Unlike the browser implementation, this relies on process.env.DEBUG containing the string nuqs.

  10. Deploy the application using Docker

    next

    The template provides optimized Dockerfiles for different package managers. Use the corresponding command to build your image and docker run to start the container on port 3000.

    # For npm
    docker build -t my-app .
    
    # For pnpm
    docker build -f Dockerfile.pnpm -t my-app .
    
    # For bun
    docker build -f Dockerfile.bun -t my-app .
    
    # Run the container
    docker run -p 3000:3000 my-app