### Start Development Server Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Start the development server using pnpm. ```bash pnpm start ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v7/README.md Installs all necessary dependencies for the project. ```bash npm install ``` -------------------------------- ### Install Nuqs with deno Source: https://github.com/47ng/nuqs/blob/next/README.md Use this command to install Nuqs using deno. ```shell deno add nuqs ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v8/README.md Installs all necessary packages for the project. Run this command after cloning the repository. ```bash npm install ``` -------------------------------- ### Install Nuqs with bun Source: https://github.com/47ng/nuqs/blob/next/README.md Use this command to install Nuqs using bun. ```shell bun add nuqs ``` -------------------------------- ### Start Remix Development Server Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/remix/README.md Run this command to start the local development server for your Remix application. ```shellscript npm run dev ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Install project dependencies using pnpm. ```bash pnpm install ``` -------------------------------- ### Install Nuqs with vlt Source: https://github.com/47ng/nuqs/blob/next/README.md Use this command to install Nuqs using vlt. ```shell vlt install nuqs ``` -------------------------------- ### Install nuqs 2.5 Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/nuqs-2.5.mdx Install the latest version of nuqs using npm. ```bash npm install nuqs@latest ``` -------------------------------- ### Install Nuqs with yarn Source: https://github.com/47ng/nuqs/blob/next/README.md Use this command to install Nuqs using yarn. ```shell yarn add nuqs ``` -------------------------------- ### Testing nuqs with Vitest and Testing Library Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/migrations/v2.mdx Utilize `NuqsTestingAdapter` to wrap components for unit testing. It provides a setup and assertion API, simplifying the testing of nuqs hooks without mocking router internals. The example demonstrates testing a counter button with initial search params and asserting URL updates. ```tsx import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { NuqsTestingAdapter, type UrlUpdateEvent } from 'nuqs/adapters/testing' import { describe, expect, it, vi } from 'vitest' import { CounterButton } from './counter-button' it('should increment the count when clicked', async () => { const user = userEvent.setup() const onUrlUpdate = vi.fn<[UrlUpdateEvent]>() render(, { // Setup the test by passing initial search params / querystring: wrapper: ({ children }) => ( {children} ) }) // Act const button = screen.getByRole('button') await user.click(button) // Assert changes in the state and in the (mocked) URL expect(button).toHaveTextContent('count is 2') expect(onUrlUpdate).toHaveBeenCalledOnce() expect(onUrlUpdate.mock.calls[0][0].queryString).toBe('?count=2') expect(onUrlUpdate.mock.calls[0][0].searchParams.get('count')).toBe('2') expect(onUrlUpdate.mock.calls[0][0].options.history).toBe('push') }) ``` -------------------------------- ### Run Development Server Source: https://github.com/47ng/nuqs/blob/next/packages/examples/next-app/README.md Commands to start the Next.js development server using different package managers. ```bash npm run dev # or yarn dev # or pnpm dev # or bun dev ``` -------------------------------- ### Install Nuqs with pnpm Source: https://github.com/47ng/nuqs/blob/next/README.md Use this command to install Nuqs using pnpm. ```shell pnpm add nuqs ``` -------------------------------- ### Install nuqs with NPM Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/installation.mdx Install the nuqs package using npm. This is the primary method for adding nuqs to your project. ```bash npm install nuqs ``` -------------------------------- ### Run Development Server Source: https://github.com/47ng/nuqs/blob/next/packages/docs/README.md Commands to start the development server for the Nuqs project using npm, pnpm, or yarn. ```bash npm run dev # or pnpm dev # or yarn dev ``` -------------------------------- ### Setup Git Hooks Source: https://github.com/47ng/nuqs/blob/next/CONTRIBUTING.md Run this command once to enable Git hooks for local linting and checks before committing or pushing. ```sh node --run setup:hooks ``` -------------------------------- ### Install nuqs with Package Managers Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/installation.mdx Install the nuqs package using your preferred package manager. Supports NPM, PNPM, Yarn, and Bun. ```bash npm install nuqs ``` ```bash pnpm add nuqs ``` ```bash yarn add nuqs ``` ```bash bun add nuqs ``` -------------------------------- ### Start Development Server Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v8/README.md Launches the development server with Hot Module Replacement (HMR) enabled for rapid development. The application will be accessible at http://localhost:5173. ```bash npm run dev ``` -------------------------------- ### Example: Parsing a User Object with Effect Schema Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/parsers/community/effect-schema.mdx Demonstrates how to use the `createSchemaParser` with a custom Effect Schema that includes composition for Base64 URL encoding and JSON parsing. This example shows setting a default value and integrating with `useQueryState`. ```typescript import { Schema } from 'effect' class User extends Schema.Class('User')({ name: Schema.String, age: Schema.Positive }) {} const ToBase64UrlEncodedJson = Schema.compose(Schema.StringFromBase64Url, Schema.parseJson()) const schema = Schema.compose(ToBase64UrlEncodedJson, User) const parser = createSchemaParser(schema).withDefault(new User({ name: 'John Vim', age: 25 })) const [user, setUser] = useQueryState('user', parser) ``` -------------------------------- ### H5 Heading Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Demonstrates a standard H5 heading in Markdown. ```markdown ##### h5 Heading ``` -------------------------------- ### H6 Heading Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Demonstrates a standard H6 heading in Markdown. ```markdown ###### h6 Heading ``` -------------------------------- ### Install React-Query Dependencies Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Add React-Query and its devtools as project dependencies using pnpm. ```bash pnpm add @tanstack/react-query @tanstack/react-query-devtools ``` -------------------------------- ### Testing nuqs Components with NuqsTestingAdapter Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/nuqs-2.mdx This example demonstrates how to test components using nuqs hooks in isolation with the NuqsTestingAdapter. It covers setting initial search parameters, simulating user events, and asserting URL changes. The adapter requires Vitest and Testing Library. ```tsx import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { NuqsTestingAdapter, type UrlUpdateEvent } from 'nuqs/adapters/testing' import { describe, expect, it, vi } from 'vitest' import { CounterButton } from './counter-button' it('should increment the count when clicked', async () => { const user = userEvent.setup() const onUrlUpdate = vi.fn<[UrlUpdateEvent]>() render(, { // 1. Setup the test by passing initial search params / querystring: wrapper: ({ children }) => ( {children} ) }) // 2. Act const button = screen.getByRole('button') await user.click(button) // 3. Assert changes in the state and in the (mocked) URL expect(button).toHaveTextContent('count is 43') expect(onUrlUpdate).toHaveBeenCalledOnce() expect(onUrlUpdate.mock.calls[0][0].queryString).toBe('?count=43') expect(onUrlUpdate.mock.calls[0][0].searchParams.get('count')).toBe('43') expect(onUrlUpdate.mock.calls[0][0].options.history).toBe('push') }) ``` -------------------------------- ### Run Remix App in Production Mode Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/remix/README.md Use this command to start your already built Remix application in a production environment. ```shell npm start ``` -------------------------------- ### H3 Heading Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Demonstrates a standard H3 heading in Markdown. ```markdown ### h3 Heading ``` -------------------------------- ### Array Type Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/nuqs-2.5.mdx Demonstrates how to handle native arrays by repeating keys in the URL, resulting in an array of values. ```typescript const arr = ['bar', 'egg'] ``` -------------------------------- ### Root Layout with Navigation Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Example of a root layout component including navigation links and TanStack Router Devtools. ```tsx import { Outlet, createRootRoute } from '@tanstack/react-router' import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' import { Link } from "@tanstack/react-router"; export const Route = createRootRoute({ component: () => ( <>
), }) ``` -------------------------------- ### H1 Heading Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Demonstrates a standard H1 heading in Markdown. ```markdown # h1 Heading ``` -------------------------------- ### URL Comparison Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/beware-the-url-type-safety-iceberg.mdx Compares two URL formats: one with simple key-value pairs and another with JSON-encoded complex state. Demonstrates the difference in URL length and readability. ```javascript import { URLComparison } from './beware-the-url-type-safety-iceberg.components' import { Suspense } from 'react'
  1. {'https://example.com?page=1&size=50&filters=genre:fantasy&sort=releaseYear:asc'}
  2. {'https://example.com?pagination=%7B%22pageIndex%22%3A1%2C%22pageSize%22%3A50%7D&filters=%5B%7B%22id%22%3A%22genre%22%2C%22value%22%3A%22fantasy%22%7D%5D&orderBy=%7B%22id%22%3A%22releaseYear%22%2C%22desc%22%3Afalse%7D'}
}>
``` -------------------------------- ### H2 Heading Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Demonstrates a standard H2 heading in Markdown. ```markdown ## h2 Heading ``` -------------------------------- ### Install TanStack Store Dependency Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Add the TanStack Store library to your project dependencies using pnpm. ```bash pnpm add @tanstack/store ``` -------------------------------- ### H4 Heading Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Demonstrates a standard H4 heading in Markdown. ```markdown #### h4 Heading ``` -------------------------------- ### Remix Adapter Setup Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/adapters.mdx Integrate Nuqs with your Remix application by wrapping your root component with the NuqsAdapter. This adapter is for Remix applications. ```tsx import { NuqsAdapter } from 'nuqs/adapters/remix' // ... export default function App() { return ( ) } ``` -------------------------------- ### React Router v7 Adapter Setup Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/adapters.mdx Wrap your root component with NuqsAdapter to enable query state management for React Router v7. ```tsx import { NuqsAdapter } from 'nuqs/adapters/react-router/v7' import { Outlet } from 'react-router' // ... export default function App() { return ( ) } ``` -------------------------------- ### React SPA Adapter Setup Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/nuqs-2.mdx This snippet shows how to integrate the nuqs adapter for a React SPA using Vite. Ensure the NuqsAdapter is imported from 'nuqs/adapters/react' and wraps your main App component. ```tsx import { createRoot } from 'react-dom/client' import App from './App' // [!code word:NuqsAdapter] import { NuqsAdapter } from 'nuqs/adapters/react' createRoot(document.getElementById('root')!).render( ) ``` -------------------------------- ### Configure History Option with Builder Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/options.mdx Use the `withOptions` method on a parser to set history behavior at the hook level. This example sets the history to 'push' for the 'foo' query state. ```typescript const [state, setState] = useQueryState( 'foo', parseAsString.withOptions({ history: 'push' }) ) ``` -------------------------------- ### Route with Data Loading Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Example of a route that uses the 'loader' functionality to fetch data before rendering. Requires 'createRoute' and 'rootRoute'. ```tsx const peopleRoute = createRoute({ getParentRoute: () => rootRoute, path: "/people", loader: async () => { const response = await fetch("https://swapi.dev/api/people"); return response.json() as Promise<{ results: { name: string; }[]; }>; }, component: () => { const data = peopleRoute.useLoaderData(); return (
    {data.results.map((person) => (
  • {person.name}
  • ))}
); }, }); ``` -------------------------------- ### Integrate Waku Adapter in _layout.tsx Source: https://github.com/47ng/nuqs/blob/next/packages/docs/src/registry/items/adapter-waku.md Wrap the children component with NuqsAdapter to integrate Waku support. This setup is typically done in your app's root layout file. ```tsx // [!code word:NuqsAdapter] import { Suspense, type ReactNode } from 'react' import { NuqsAdapter } from './nuqs-waku-adapter' type LayoutProps = { children: ReactNode } export default async function Layout({ children }: LayoutProps) { return ( <> {children} ) } export const getConfig = async () => { return { render: 'dynamic' // render: 'static', // works but can cause hydration warnings } as const } ``` -------------------------------- ### Set up React-Query Client and Provider Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Initialize a QueryClient and wrap your application with QueryClientProvider in main.tsx. ```tsx import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; // ... const queryClient = new QueryClient(); // ... if (!rootElement.innerHTML) { const root = ReactDOM.createRoot(rootElement); root.render( ); } ``` -------------------------------- ### Build for Production Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Build the application for production using pnpm. ```bash pnpm build ``` -------------------------------- ### Initialize Testing Adapter with Query String Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/testing.mdx Use `withNuqsTestingAdapter` with an initial search params query string. ```tsx withNuqsTestingAdapter({ searchParams: '?q=hello&limit=10' }) ``` -------------------------------- ### Feature Support Matrix (Introduced with Frameworks) Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Displays feature support, including the introduction version and a list of supported frameworks. ```jsx ``` -------------------------------- ### Build for Production Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v8/README.md Generates an optimized production build of the application, including client and server code. ```bash npm run build ``` -------------------------------- ### Docker Build for bun Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v8/README.md Builds a Docker image for the application using bun as the package manager. Specifies the Dockerfile.bun and tags the image as 'my-app'. ```bash # For bun docker build -f Dockerfile.bun -t my-app . ``` -------------------------------- ### Build Remix App for Production Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/remix/README.md Execute this command to create an optimized production build of your Remix application. ```shell npm run build ``` -------------------------------- ### Docker Build for bun Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v7/README.md Builds a Docker image for the application using bun as the package manager. ```bash docker build -f Dockerfile.bun -t my-app . ``` -------------------------------- ### React SPA Initialization Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/adapters.mdx Initialize NuqsAdapter for a React Single Page Application, shown with Vite. ```tsx import { NuqsAdapter } from 'nuqs/adapters/react' createRoot(document.getElementById('root')!).render( ) ``` -------------------------------- ### React Router v8 Adapter Setup Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/adapters.mdx Use the NuqsAdapter for React Router v8. This adapter currently re-exports the v7 adapter. ```tsx import { NuqsAdapter } from 'nuqs/adapters/react-router/v8' import { Outlet } from 'react-router' // ... export default function App() { return ( ) } ``` -------------------------------- ### React Router v6 Adapter Setup Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/adapters.mdx Set up the NuqsAdapter for React Router v6 applications. Ensure you are using createBrowserRouter. Note that this adapter is deprecated. ```tsx import { NuqsAdapter } from 'nuqs/adapters/react-router/v6' import { createBrowserRouter, RouterProvider } from 'react-router-dom' import App from './App' const router = createBrowserRouter([ { path: '/', element: } ]) export function ReactRouter() { return ( ) } ``` -------------------------------- ### TanStack Router Adapter Setup Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/adapters.mdx Integrate Nuqs with TanStack Router by wrapping your root route component with NuqsAdapter. Note: TanStack Router support is experimental. ```tsx import { NuqsAdapter } from 'nuqs/adapters/tanstack-router' import { Outlet, createRootRoute } from '@tanstack/react-router' export const Route = createRootRoute({ component: () => ( <> ), }) ``` -------------------------------- ### Initialize Testing Adapter with URLSearchParams Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/testing.mdx Initialize the testing adapter using a `URLSearchParams` object. ```tsx withNuqsTestingAdapter({ searchParams: new URLSearchParams('?q=hello&limit=10') }) ``` -------------------------------- ### Infer Type of Individual Parser Source: https://github.com/47ng/nuqs/blob/next/README.md Use `inferParserType` to get the TypeScript type of a single nuqs parser, including nullable types for parsers without a default value. ```typescript import { parseAsInteger, type inferParserType } from 'nuqs' // or 'nuqs/server' const intNullable = parseAsInteger const intNonNull = parseAsInteger.withDefault(0) inferParserType // number | null inferParserType // number ``` -------------------------------- ### Setting Default Values for useQueryState Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/basic-usage.mdx Demonstrates how to provide default values for `useQueryState` using either the `defaultValue` option or the `.withDefault()` builder method on parsers. This ensures a predictable state when the query parameter is absent or invalid. ```ts const [search] = useQueryState('search', { defaultValue: '' }) // ^? string const [count] = useQueryState('count', parseAsInteger) // ^? number | null -> no default value = nullable const [count] = useQueryState('count', parseAsInteger.withDefault(0)) // ^? number ``` -------------------------------- ### Run Tests Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Run project tests using Vitest via pnpm. ```bash pnpm test ``` -------------------------------- ### Initialize Testing Adapter with Record Object Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/testing.mdx Provide initial search parameters as a record object. Note that values are serialized strings. ```tsx withNuqsTestingAdapter({ searchParams: { q: 'hello', limit: '10' // Values are serialized strings } }) ``` -------------------------------- ### TanStack Router Type-Safe Routing with `validateSearch` Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/adapters.mdx Leverage TanStack Router's `validateSearch` with Nuqs' standard schema for type-safe search parameters. This example demonstrates defining and consuming search parameters. ```tsx import { createFileRoute, Link } from '@tanstack/react-router' import { createStandardSchemaV1, parseAsIndex, parseAsString, useQueryStates } from 'nuqs' const searchParams = { searchQuery: parseAsString.withDefault(''), pageIndex: parseAsIndex.withDefault(0), } export const Route = createFileRoute('/search')({ component: RouteComponent, validateSearch: createStandardSchemaV1(searchParams, { partialOutput: true }) }) function RouteComponent() { // Consume nuqs state as usual: const [{ searchQuery, pageIndex }] = useQueryStates(searchParams) // But now TanStack Router knows about it too: return ( ) } ``` -------------------------------- ### Define and Use Coordinate Parsers and Cache Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/server-side.mdx Define parsers for floating-point numbers and create a cache for latitude and longitude search parameters. This example demonstrates sharing parsers between server and client components. ```typescript import { parseAsFloat, createSearchParamsCache } from 'nuqs/server' export const coordinatesParsers = { lat: parseAsFloat.withDefault(45.18), lng: parseAsFloat.withDefault(5.72) } export const coordinatesCache = createSearchParamsCache(coordinatesParsers) ``` -------------------------------- ### Custom Lossy Serializer Example Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/parsers/making-your-own.mdx Demonstrates creating a custom parser with a lossy serializer using `toFixed(4)` which loses precision when serializing floating-point numbers. This can lead to incorrect state restoration. ```typescript const geoCoordParser = { parse: parseFloat, serialize: v => v.toFixed(4) // Loses precision } const [lat, setLat] = useQueryState('lat', geoCoordParser) ``` -------------------------------- ### Gate Content with SinceVersion Component Source: https://github.com/47ng/nuqs/blob/next/packages/docs/CLAUDE.md Wrap new feature documentation within the `` component to hide it on production until the specified version is released. Ensure the version number matches the upcoming release. ```mdx ## My new feature ... ``` -------------------------------- ### Awaiting URL Updates After Batching Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/batching.mdx Await the Promise returned by a state updater function to get the updated URLSearchParams object after batched updates have been applied. This allows you to inspect the final URL state. ```typescript const randomCoordinates = React.useCallback(() => { setLat(42) return setLng(12) }, []) randomCoordinates().then((search: URLSearchParams) => { search.get('lat') // 42 search.get('lng') // 12, has been queued and batch-updated }) ``` -------------------------------- ### Create Derived State with TanStack Store Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Shows how to create a derived store that automatically updates when its base state changes. The Derived class requires mounting to activate. ```tsx import { useStore } from "@tanstack/react-store"; import { Store, Derived } from "@tanstack/store"; import "./App.css"; const countStore = new Store(0); const doubledStore = new Derived({ fn: () => countStore.state * 2, deps: [countStore], }); doubledStore.mount(); function App() { const count = useStore(countStore); const doubledCount = useStore(doubledStore); return (
Doubled - {doubledCount}
); } export default App; ``` -------------------------------- ### Enable Scrolling with State Updater Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/options.mdx Pass an options object as the second argument to the state updater function to control behavior like scrolling. This example enables scrolling to the top of the page when the state is updated. ```typescript setState('foo', { scroll: true }) ``` -------------------------------- ### Parse Coordinates in Page Component with Strict Mode Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/server-side.mdx Parse search parameters in the Page component, optionally using strict mode for validation. This setup prepares for rendering Server and Client components that utilize these parameters. ```tsx import { coordinatesCache } from './searchParams' import { Server } from './server' import { Client } from './client' export default async function Page({ searchParams }) { // Note: you can also use strict mode here: await coordinatesCache.parse(searchParams, { strict: true }) return ( <> ) } ``` -------------------------------- ### Import InlineSponsorsList and VercelOssBadge Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/nuqs-2.5.mdx Imports necessary components for displaying sponsor information and Vercel OSS badge. ```javascript import { InlineSponsorsList } from '@/src/app/(pages)/_landing/sponsors' import { VercelOssBadge } from '@/src/components/vercel-oss-badge' ``` -------------------------------- ### Use Optimistic Search Params in React Router Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/options.mdx Import `useOptimisticSearchParams` from `nuqs/adapters` to get a reactive, read-only search params object that reflects shallow updates. This is necessary because the stock `useSearchParams` hook does not reflect these changes. ```tsx import { useOptimisticSearchParams } from 'nuqs/adapters/remix' // or '…/react-router/v{6,7,8}' function Component() { // Note: this is read-only, but reactive to all URL changes const searchParams = useOptimisticSearchParams() return
{searchParams.get('foo')}
} ``` -------------------------------- ### Run Docker Container Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v8/README.md Runs the built Docker container, mapping port 3000 on the host to port 3000 in the container. Assumes the image is named 'my-app'. ```bash # Run the container docker run -p 3000:3000 my-app ``` -------------------------------- ### Parse Native Array of Integers Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/parsers/built-in.mdx Use `parseAsNativeArrayOf` with `parseAsInteger` to handle repeating query parameters as a typed array. This example demonstrates reading and writing URL parameters like '?project=123&project=456' into a TypeScript array of numbers. ```tsx import { useQueryState, parseAsNativeArrayOf, parseAsInteger } from 'nuqs' const [projectIds, setProjectIds] = useQueryState( 'project', parseAsNativeArrayOf(parseAsInteger) ) // ?project=123&project=456 → [123, 456] ``` -------------------------------- ### Wrapping Client Components in Suspense Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/troubleshooting.mdx Client components using hooks like useQueryState must be wrapped in a Suspense boundary to prevent Next.js errors related to CSR bailouts. This example shows the recommended approach of separating server and client files. ```tsx 'use client' export default function Page() { return ( ) } function Client() { const [foo, setFoo] = useQueryState('foo') // ... } ``` -------------------------------- ### Docker Build for pnpm Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v8/README.md Builds a Docker image for the application using pnpm as the package manager. Specifies the Dockerfile.pnpm and tags the image as 'my-app'. ```bash # For pnpm docker build -f Dockerfile.pnpm -t my-app . ``` -------------------------------- ### Generate Canonical URL with Query Strings in Next.js Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/seo.mdx When query strings define page content (e.g., video IDs), generate a canonical URL that includes relevant query strings using nuqs server utilities. This example demonstrates parsing and serializing YouTube video IDs. ```typescript import type { Metadata, ResolvingMetadata } from 'next' import { notFound } from "next/navigation"; import { createParser, parseAsString, createLoader, createSerializer, type SearchParams, type UrlKeys } from 'nuqs/server' const youTubeVideoIdRegex = /^[^"&?\/\s]{11}$/i const youTubeSearchParams = { videoId: createParser({ parse(query) { if (!youTubeVideoIdRegex.test(query)) { return null } return query }, serialize(videoId) { return videoId } }) } const youTubeUrlKeys: UrlKeys = { videoId: 'v' } const loadYouTubeSearchParams = createLoader( youTubeSearchParams, { urlKeys: youTubeUrlKeys } ) const serializeYouTubeSearchParams = createSerializer( youTubeSearchParams, { urlKeys: youTubeUrlKeys } ) // -- type Props = { searchParams: Promise } export async function generateMetadata({ searchParams }: Props): Promise { const { videoId } = await loadYouTubeSearchParams(searchParams) if (!videoId) { notFound() } return { alternates: { canonical: serializeYouTubeSearchParams('/watch', { videoId }) // /watch?v=dQw4w9WgXcQ } } } ``` -------------------------------- ### Create a Simple Counter with TanStack Store Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/tanstack-router/README.md Demonstrates creating a basic counter store and using the useStore hook to display and update the count in a React component. ```tsx import { useStore } from "@tanstack/react-store"; import { Store } from "@tanstack/store"; import "./App.css"; const countStore = new Store(0); function App() { const count = useStore(countStore); return (
); } export default App; ``` -------------------------------- ### Docker Build for npm Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v8/README.md Builds a Docker image for the application using npm as the package manager. The image is tagged as 'my-app'. ```bash # For npm docker build -t my-app . ``` -------------------------------- ### Docker Build for pnpm Source: https://github.com/47ng/nuqs/blob/next/packages/e2e/react-router/v7/README.md Builds a Docker image for the application using pnpm as the package manager. ```bash docker build -f Dockerfile.pnpm -t my-app . ``` -------------------------------- ### Enable Debug Logs with Wildcards Source: https://github.com/47ng/nuqs/blob/next/README.md Combine 'nuqs' with wildcards in localStorage to enable debug logs for Nuqs and other packages. Reload the page after setting the item. ```javascript localStorage.setItem('debug', '*,nuqs') ``` -------------------------------- ### Batching URL Updates with useQueryState Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/beware-the-url-type-safety-iceberg.mdx Demonstrates how multiple calls to useQueryState can be batched into a single URL update, preventing issues with browser rate limiting. This is useful for updating related states simultaneously. ```typescript const [lat, setLat] = useQueryState('lat', parseAsFloat) const [lng, setLng] = useQueryState('lng', parseAsFloat) const randomCoordinates = () => { // These will be batched into a single URL update setLat(Math.random() * 180 - 90) setLng(Math.random() * 360 - 180) } ``` -------------------------------- ### Sync Input State with URL using useQueryState Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/basic-usage.mdx Use `useQueryState` to manage an input's value and synchronize it with a URL query parameter. Setting the state to `null` removes the key from the URL. ```tsx "use client" import { useQueryState } from 'nuqs' export function Demo() { const [name, setName] = useQueryState('name') return ( <> setName(e.target.value)} />

Hello, {name || 'anonymous visitor'}!

) } ``` -------------------------------- ### Unit Test Component with useQueryState Source: https://github.com/47ng/nuqs/blob/next/README.md Utilize the `NuqsTestingAdapter` with Testing Library and Vitest to unit test components using `useQueryState` or `useQueryStates` in isolation. Provide initial search parameters and a callback for URL updates. ```tsx import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { NuqsTestingAdapter, type UrlUpdateEvent } from 'nuqs/adapters/testing' import { describe, expect, it, vi } from 'vitest' import { CounterButton } from './counter-button' it('should increment the count when clicked', async () => { const user = userEvent.setup() const onUrlUpdate = vi.fn<[UrlUpdateEvent]>() render(, { // Setup the test by passing initial search params / querystring, // and give it a function to call on URL updates wrapper: ({ children }) => ( {children} ) }) // Initial state assertions: there's a clickable button displaying the count const button = screen.getByRole('button') expect(button).toHaveTextContent('count is 42') // Act await user.click(button) // Assert changes in the state and in the (mocked) URL expect(button).toHaveTextContent('count is 43') expect(onUrlUpdate).toHaveBeenCalledOnce() expect(onUrlUpdate.mock.calls[0][0].queryString).toBe('?count=43') expect(onUrlUpdate.mock.calls[0][0].searchParams.get('count')).toBe('43') expect(onUrlUpdate.mock.calls[0][0].options.history).toBe('push') }) ``` -------------------------------- ### Verify npm Package Release Locally Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/blog/staged-publishing-for-supply-chain-security.mdx Run this command to verify a specific version of an npm package locally. It fetches published metadata, builds a canonical image, and compares reproduced hashes with published ones. ```shell $ pnpm verify v2.9.0 ==> Fetching tag v2.9.0 ==> Reading published metadata for nuqs@2.9.0 integrity : sha512-1ckQBhVHaQYjLZ3kWhhH40A32lPJ7TNTQMa2T+SUvl5azyVt7swCQfUXt9xOXJV3YidWq8VHIHcMzVAJ0knRsw== shasum : 398efd8c07a46ef1e819c1bf93df176510fd7b5b gitHead : 29990b5ffca4b5041202ca46799cd43542d4fcb8 tag commit: 29990b5ffca4b5041202ca46799cd43542d4fcb8 ==> Building canonical image (node 24.11.0, npm 11.16.0, pnpm 11.0.9) ==> Reproducing nuqs@2.9.0 from v2.9.0 ================================================================== package : nuqs@2.9.0 reproduced .tgz : nuqs-2.9.0.tgz ================================================================== reproduced integrity : sha512-1ckQBhVHaQYjLZ3kWhhH40A32lPJ7TNTQMa2T+SUvl5azyVt7swCQfUXt9xOXJV3YidWq8VHIHcMzVAJ0knRsw== published integrity : sha512-1ckQBhVHaQYjLZ3kWhhH40A32lPJ7TNTQMa2T+SUvl5azyVt7swCQfUXt9xOXJV3YidWq8VHIHcMzVAJ0knRsw== reproduced shasum : 398efd8c07a46ef1e819c1bf93df176510fd7b5b published shasum : 398efd8c07a46ef1e819c1bf93df176510fd7b5b ==> PASS — nuqs@2.9.0 reproduces from v2.9.0 ``` -------------------------------- ### Feature Support Matrix (Introduced with Next.js) Source: https://github.com/47ng/nuqs/blob/next/packages/docs/content/docs/internal/design-system.mdx Displays feature support, including the introduction version and support for Next.js app router. ```jsx ```