Full Code of 47ng/nuqs for AI

next 61e126a55651 cached
1140 files
1.6 MB
568.3k tokens
1224 symbols
1 requests
Download .txt
Showing preview only (1,970K chars total). Download the full file or copy to clipboard to get everything.
Repository: 47ng/nuqs
Branch: next
Commit: 61e126a55651
Files: 1140
Total size: 1.6 MB

Directory structure:
gitextract_4cpkr29x/

├── .agents/
│   └── docs/
│       ├── adapter-development.md
│       ├── api-design.md
│       ├── git-workflow.md
│       ├── parser-implementation.md
│       ├── quality-standards.md
│       └── testing.md
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── config.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── analyse-nextjs-release.yml
│       ├── ci-cd.yml
│       ├── clear-shipping-next.yml
│       ├── milestone-automation.yml
│       ├── pkg.pr.new.yml
│       ├── pr-base-enforcement.yml
│       ├── pr-lint.yml
│       └── test-against-nextjs-release.yml
├── .gitignore
├── .husky/
│   └── commit-msg
├── .node-version
├── .vscode/
│   └── settings.json
├── AGENTS.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── errors/
│   ├── NUQS-101.md
│   ├── NUQS-303.md
│   ├── NUQS-404.md
│   ├── NUQS-409.md
│   ├── NUQS-414.md
│   ├── NUQS-422.md
│   ├── NUQS-429.md
│   ├── NUQS-500.md
│   └── NUQS-501.md
├── package.json
├── packages/
│   ├── docs/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── components.json
│   │   ├── content/
│   │   │   ├── blog/
│   │   │   │   ├── 2025.mdx
│   │   │   │   ├── beware-the-url-type-safety-iceberg.components.tsx
│   │   │   │   ├── beware-the-url-type-safety-iceberg.mdx
│   │   │   │   ├── nuqs-2.5-key-isolation.client.tsx
│   │   │   │   ├── nuqs-2.5.mdx
│   │   │   │   ├── nuqs-2.mdx
│   │   │   │   ├── open-source-pledge-recipient.tsx
│   │   │   │   └── open-source-pledge.mdx
│   │   │   └── docs/
│   │   │       ├── about.mdx
│   │   │       ├── adapters.mdx
│   │   │       ├── basic-usage.mdx
│   │   │       ├── batching.mdx
│   │   │       ├── debugging.mdx
│   │   │       ├── installation.mdx
│   │   │       ├── internal/
│   │   │       │   └── design-system.mdx
│   │   │       ├── limits.mdx
│   │   │       ├── meta.json
│   │   │       ├── migrations/
│   │   │       │   └── v2.mdx
│   │   │       ├── options.client.tsx
│   │   │       ├── options.mdx
│   │   │       ├── parsers/
│   │   │       │   ├── built-in.mdx
│   │   │       │   ├── community/
│   │   │       │   │   ├── effect-schema-demo.tsx
│   │   │       │   │   ├── effect-schema.mdx
│   │   │       │   │   ├── meta.json
│   │   │       │   │   ├── tanstack-table.generator.tsx
│   │   │       │   │   ├── tanstack-table.mdx
│   │   │       │   │   ├── zod-codecs.demo.tsx
│   │   │       │   │   ├── zod-codecs.lib.ts
│   │   │       │   │   ├── zod-codecs.mdx
│   │   │       │   │   ├── zod-codecs.skeleton.tsx
│   │   │       │   │   └── zod-codecs.source.tsx
│   │   │       │   ├── demos.tsx
│   │   │       │   ├── making-your-own.mdx
│   │   │       │   └── meta.json
│   │   │       ├── seo.mdx
│   │   │       ├── server-side.mdx
│   │   │       ├── testing.mdx
│   │   │       ├── tips-tricks.mdx
│   │   │       ├── troubleshooting.mdx
│   │   │       └── utilities.mdx
│   │   ├── mdx-components.tsx
│   │   ├── next.config.mjs
│   │   ├── package.json
│   │   ├── public/
│   │   │   └── .well-known/
│   │   │       └── atproto-did
│   │   ├── rehype-code.config.ts
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── source.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (llms)/
│   │   │   │   │   ├── llms/
│   │   │   │   │   │   └── [...slug]/
│   │   │   │   │   │       └── route.tsx
│   │   │   │   │   ├── llms-full.txt/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── llms.txt/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── (pages)/
│   │   │   │   │   ├── (confs)/
│   │   │   │   │   │   ├── nextjs-conf-25/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── react-advanced-25/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── react-paris/
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── _landing/
│   │   │   │   │   │   ├── bundle-size.tsx
│   │   │   │   │   │   ├── contributors.tsx
│   │   │   │   │   │   ├── demo.client.tsx
│   │   │   │   │   │   ├── demo.tsx
│   │   │   │   │   │   ├── dependents.tsx
│   │   │   │   │   │   ├── features.tsx
│   │   │   │   │   │   ├── gha-status.tsx
│   │   │   │   │   │   ├── hero.tsx
│   │   │   │   │   │   ├── page-footer.tsx
│   │   │   │   │   │   ├── quotes/
│   │   │   │   │   │   │   └── quotes-section.tsx
│   │   │   │   │   │   ├── sponsors.tsx
│   │   │   │   │   │   └── works-with.tsx
│   │   │   │   │   ├── blog/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   │   └── author.tsx
│   │   │   │   │   │   │   ├── opengraph-image.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── twitter-image.tsx
│   │   │   │   │   │   ├── _lib/
│   │   │   │   │   │   │   └── source.ts
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── rss.xml/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── stats/
│   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   ├── downloads.client.tsx
│   │   │   │   │   │   │   ├── downloads.tsx
│   │   │   │   │   │   │   ├── graph.skeleton.tsx
│   │   │   │   │   │   │   ├── partial-line.tsx
│   │   │   │   │   │   │   ├── stars.client.tsx
│   │   │   │   │   │   │   ├── stars.gazers-list.tsx
│   │   │   │   │   │   │   ├── stars.tsx
│   │   │   │   │   │   │   ├── versions.tsx
│   │   │   │   │   │   │   ├── widget.skeleton.tsx
│   │   │   │   │   │   │   └── widget.tsx
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   ├── format.ts
│   │   │   │   │   │   │   ├── github.ts
│   │   │   │   │   │   │   ├── npm.ts
│   │   │   │   │   │   │   ├── svg.ts
│   │   │   │   │   │   │   └── versions.ts
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── searchParams.ts
│   │   │   │   │   └── users/
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── isr/
│   │   │   │   │   │   ├── .gitignore
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── search/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── banners.tsx
│   │   │   │   ├── docs/
│   │   │   │   │   ├── [[...slug]]/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   └── layout.tsx
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── not-found.tsx
│   │   │   │   ├── playground/
│   │   │   │   │   ├── (demos)/
│   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   └── source-on-github.tsx
│   │   │   │   │   │   ├── basic-counter/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── batching/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── demos.ts
│   │   │   │   │   │   ├── hex-colors/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── pagination/
│   │   │   │   │   │   │   ├── api.ts
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── pagination-controls.client.tsx
│   │   │   │   │   │   │   ├── pagination-controls.server.tsx
│   │   │   │   │   │   │   ├── product.tsx
│   │   │   │   │   │   │   ├── rendering-controls.tsx
│   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   └── tic-tac-toe/
│   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── _demos/
│   │   │   │   │   │   ├── builder-pattern/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── compound-parsers/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── crosslink/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── custom-parser/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── parsers/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── pretty-urls/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-359/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-376/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-907/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── server-side-parsing/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── parser.ts
│   │   │   │   │   │   └── throttling/
│   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │       ├── page.tsx
│   │   │   │   │   │       └── parsers.ts
│   │   │   │   │   ├── debug-control.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── registry/
│   │   │   │   │   ├── [name]/
│   │   │   │   │   │   ├── author.tsx
│   │   │   │   │   │   ├── opengraph-image.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── twitter-image.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── rss.xml/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── robots.ts
│   │   │   │   ├── sitemap.ts
│   │   │   │   ├── source.ts
│   │   │   │   └── styles/
│   │   │   │       └── tweaks.css
│   │   │   ├── components/
│   │   │   │   ├── 47ng.tsx
│   │   │   │   ├── ai/
│   │   │   │   │   └── page-actions.tsx
│   │   │   │   ├── audience.tsx
│   │   │   │   ├── code-block-defs.ts
│   │   │   │   ├── code-block-highlighter.skeleton.ts
│   │   │   │   ├── code-block-highlighter.ts
│   │   │   │   ├── code-block.client.tsx
│   │   │   │   ├── code-block.tsx
│   │   │   │   ├── countdown.tsx
│   │   │   │   ├── favicon.tsx
│   │   │   │   ├── feature-support-matrix.tsx
│   │   │   │   ├── frameworks.client.tsx
│   │   │   │   ├── frameworks.tsx
│   │   │   │   ├── github-profile.tsx
│   │   │   │   ├── kibo-ui/
│   │   │   │   │   └── contribution-graph/
│   │   │   │   │       └── index.tsx
│   │   │   │   ├── link-tree.tsx
│   │   │   │   ├── logo.tsx
│   │   │   │   ├── og-image.tsx
│   │   │   │   ├── query-spy.tsx
│   │   │   │   ├── querystring.tsx
│   │   │   │   ├── quote.tsx
│   │   │   │   ├── react-paris.tsx
│   │   │   │   ├── release-contribution-graph.client.tsx
│   │   │   │   ├── release-contribution-graph.tsx
│   │   │   │   ├── responsive-helpers.tsx
│   │   │   │   ├── shared-layout.tsx
│   │   │   │   ├── sidebar-footer.tsx
│   │   │   │   ├── typography.tsx
│   │   │   │   ├── ui/
│   │   │   │   │   ├── badge.tsx
│   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   ├── button.tsx
│   │   │   │   │   ├── card.tsx
│   │   │   │   │   ├── chart.tsx
│   │   │   │   │   ├── checkbox.tsx
│   │   │   │   │   ├── input.tsx
│   │   │   │   │   ├── label.tsx
│   │   │   │   │   ├── pagination.tsx
│   │   │   │   │   ├── popover.tsx
│   │   │   │   │   ├── pr-line.tsx
│   │   │   │   │   ├── select.tsx
│   │   │   │   │   ├── separator.tsx
│   │   │   │   │   ├── slider.tsx
│   │   │   │   │   ├── switch.tsx
│   │   │   │   │   ├── tabs.tsx
│   │   │   │   │   ├── toggle-group.tsx
│   │   │   │   │   ├── toggle.tsx
│   │   │   │   │   ├── tooltip-popover.tsx
│   │   │   │   │   └── tooltip.tsx
│   │   │   │   └── vercel-oss-badge.tsx
│   │   │   ├── instrumentation-client.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── get-last-modified.ts
│   │   │   │   ├── get-llm-text.ts
│   │   │   │   ├── remark-audience.ts
│   │   │   │   ├── typed-links.ts
│   │   │   │   ├── url.ts
│   │   │   │   └── utils.ts
│   │   │   └── registry/
│   │   │       ├── assemble.ts
│   │   │       ├── items/
│   │   │       │   ├── adapter-inertia.json
│   │   │       │   ├── adapter-inertia.md
│   │   │       │   ├── adapter-onejs.json
│   │   │       │   ├── adapter-onejs.md
│   │   │       │   ├── adapter-onejs.source
│   │   │       │   ├── adapter-react-router-v5.json
│   │   │       │   ├── adapter-react-router-v5.md
│   │   │       │   ├── adapter-react-router-v5.source
│   │   │       │   ├── adapter-waku.json
│   │   │       │   ├── adapter-waku.md
│   │   │       │   ├── next-typed-links.json
│   │   │       │   └── next-typed-links.md
│   │   │       ├── read.ts
│   │   │       ├── remote/
│   │   │       │   └── .gitignore
│   │   │       └── schemas.ts
│   │   ├── tsconfig.json
│   │   └── turbo.json
│   ├── e2e/
│   │   ├── next/
│   │   │   ├── .gitignore
│   │   │   ├── next-env.d.ts
│   │   │   ├── next.config.mjs
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── scripts/
│   │   │   │   └── cache-components-codemod.ts
│   │   │   ├── specs/
│   │   │   │   ├── cache.spec.ts
│   │   │   │   ├── deferred.spec.ts
│   │   │   │   ├── multitenant.spec.ts
│   │   │   │   ├── persist-across-navigation.spec.ts
│   │   │   │   ├── push.spec.ts
│   │   │   │   ├── referential-equality.spec.ts
│   │   │   │   ├── remapped-keys.spec.ts
│   │   │   │   ├── repros.spec.ts
│   │   │   │   ├── rewrites.spec.ts
│   │   │   │   ├── routing-tour.spec.ts
│   │   │   │   ├── shared/
│   │   │   │   │   ├── basic-io-agnostic.spec.ts
│   │   │   │   │   ├── debounce.spec.ts
│   │   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   │   ├── hash-preservation.spec.ts
│   │   │   │   │   ├── loader.spec.ts
│   │   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   └── stitching.spec.ts
│   │   │   │   ├── shared.spec.ts
│   │   │   │   ├── transitions.spec.ts
│   │   │   │   ├── useQueryState.spec.ts
│   │   │   │   ├── useQueryStates-clear-all.spec.ts
│   │   │   │   ├── useQueryStates.spec.ts
│   │   │   │   └── useSearchParams.spec.ts
│   │   │   ├── src/
│   │   │   │   ├── app/
│   │   │   │   │   ├── api/
│   │   │   │   │   │   └── app/
│   │   │   │   │   │       └── loader/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   ├── app/
│   │   │   │   │   │   ├── (shared)/
│   │   │   │   │   │   │   ├── basic-io/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── conditional-rendering/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── debounce/
│   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── dynamic-segments/
│   │   │   │   │   │   │   │   ├── catch-all/
│   │   │   │   │   │   │   │   │   └── [...segments]/
│   │   │   │   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   │   └── [segment]/
│   │   │   │   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   └── optional-catch-all/
│   │   │   │   │   │   │   │       └── [[...segments]]/
│   │   │   │   │   │   │   │           ├── client.tsx
│   │   │   │   │   │   │   │           └── page.tsx
│   │   │   │   │   │   │   ├── flush-after-navigate/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── end/
│   │   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   │   └── start/
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── end/
│   │   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │   │       └── start/
│   │   │   │   │   │   │   │           └── page.tsx
│   │   │   │   │   │   │   ├── form/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── hash-preservation/
│   │   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── history-sync/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── json/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── life-and-death/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── linking/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── other/
│   │   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── native-array/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── popstate-queue-reset/
│   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── pretty-urls/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── push/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── dynamic/
│   │   │   │   │   │   │   │       │   └── [route]/
│   │   │   │   │   │   │   │       │       └── page.tsx
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── rate-limits/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── referential-stability/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── render-count/
│   │   │   │   │   │   │   │   └── [hook]/
│   │   │   │   │   │   │   │       └── [shallow]/
│   │   │   │   │   │   │   │           └── [history]/
│   │   │   │   │   │   │   │               └── [startTransition]/
│   │   │   │   │   │   │   │                   └── page.tsx
│   │   │   │   │   │   │   ├── repro-1365/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── repro-359/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── repro-982/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── routing/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── other/
│   │   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── scroll/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── shallow/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   └── stitching/
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── agnostic/
│   │   │   │   │   │   │   ├── basic-io/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── layout.tsx
│   │   │   │   │   │   ├── cache/
│   │   │   │   │   │   │   ├── all.tsx
│   │   │   │   │   │   │   ├── get.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── searchParams.ts
│   │   │   │   │   │   │   └── set.tsx
│   │   │   │   │   │   ├── deferred/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── loader/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── multitenant/
│   │   │   │   │   │   │   └── [tenant]/
│   │   │   │   │   │   │       ├── client-tenant.tsx
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── persist-across-navigation/
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── b/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── client.tsx
│   │   │   │   │   │   ├── push/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── searchParams.ts
│   │   │   │   │   │   ├── referential-equality/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── remapped-keys/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-1099/
│   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── repro-1293/
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── b/
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── repro-388/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-498/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-542/
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── b/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── client.tsx
│   │   │   │   │   │   ├── repro-630/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-758/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-760/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-774/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── rewrites/
│   │   │   │   │   │   │   └── destination/
│   │   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │   │       ├── page.tsx
│   │   │   │   │   │   │       └── searchParams.ts
│   │   │   │   │   │   ├── routing-tour/
│   │   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   │   ├── parsers.ts
│   │   │   │   │   │   │   │   └── view.tsx
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── b/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── c/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── d/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── start/
│   │   │   │   │   │   │       ├── client/
│   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │       └── server/
│   │   │   │   │   │   │           └── page.tsx
│   │   │   │   │   │   ├── template/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── transitions/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── useQueryStates/
│   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── useQueryStates-clear-all/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── useSearchParams/
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── providers.tsx
│   │   │   │   ├── components/
│   │   │   │   │   └── pages-ready-wrapper.tsx
│   │   │   │   ├── middleware.ts
│   │   │   │   └── pages/
│   │   │   │       ├── _app.tsx
│   │   │   │       ├── api/
│   │   │   │       │   └── pages/
│   │   │   │       │       └── loader.ts
│   │   │   │       └── pages/
│   │   │   │           ├── agnostic/
│   │   │   │           │   └── basic-io.tsx
│   │   │   │           ├── basic-io/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── conditional-rendering/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── debounce/
│   │   │   │           │   ├── index.tsx
│   │   │   │           │   └── other.tsx
│   │   │   │           ├── dynamic-segments/
│   │   │   │           │   ├── catch-all/
│   │   │   │           │   │   └── [...segments].tsx
│   │   │   │           │   ├── dynamic/
│   │   │   │           │   │   └── [segment].tsx
│   │   │   │           │   └── optional-catch-all/
│   │   │   │           │       └── [[...segments]].tsx
│   │   │   │           ├── flush-after-navigate/
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── end.tsx
│   │   │   │           │   │   └── start.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── end.tsx
│   │   │   │           │       └── start.tsx
│   │   │   │           ├── form/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── hash-preservation/
│   │   │   │           │   ├── dynamic/
│   │   │   │           │   │   └── [route]/
│   │   │   │           │   │       └── index.tsx
│   │   │   │           │   └── index.tsx
│   │   │   │           ├── history-sync.tsx
│   │   │   │           ├── json.tsx
│   │   │   │           ├── life-and-death.tsx
│   │   │   │           ├── linking/
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── index.tsx
│   │   │   │           │   │   └── other.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── index.tsx
│   │   │   │           │       └── other.tsx
│   │   │   │           ├── loader.tsx
│   │   │   │           ├── middleware.tsx
│   │   │   │           ├── multitenant/
│   │   │   │           │   └── [tenant].tsx
│   │   │   │           ├── native-array.tsx
│   │   │   │           ├── popstate-queue-reset/
│   │   │   │           │   ├── index.tsx
│   │   │   │           │   └── other.tsx
│   │   │   │           ├── pretty-urls.tsx
│   │   │   │           ├── push/
│   │   │   │           │   ├── index.tsx
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── dynamic/
│   │   │   │           │   │   │   └── [route]/
│   │   │   │           │   │   │       └── index.tsx
│   │   │   │           │   │   └── index.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── dynamic/
│   │   │   │           │       │   └── [route]/
│   │   │   │           │       │       └── index.tsx
│   │   │   │           │       └── index.tsx
│   │   │   │           ├── rate-limits.tsx
│   │   │   │           ├── referential-stability/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── render-count/
│   │   │   │           │   └── [hook]/
│   │   │   │           │       └── [shallow]/
│   │   │   │           │           └── [history]/
│   │   │   │           │               └── [startTransition]/
│   │   │   │           │                   └── index.tsx
│   │   │   │           ├── repro-1099/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── repro-1293/
│   │   │   │           │   ├── a.tsx
│   │   │   │           │   └── b.tsx
│   │   │   │           ├── repro-1365.tsx
│   │   │   │           ├── repro-359.tsx
│   │   │   │           ├── repro-982.tsx
│   │   │   │           ├── routing/
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── index.tsx
│   │   │   │           │   │   └── other.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── index.tsx
│   │   │   │           │       └── other.tsx
│   │   │   │           ├── scroll.tsx
│   │   │   │           ├── shallow/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── stitching.tsx
│   │   │   │           ├── useQueryState/
│   │   │   │           │   ├── dynamic/
│   │   │   │           │   │   └── [route]/
│   │   │   │           │   │       └── index.tsx
│   │   │   │           │   └── index.tsx
│   │   │   │           └── useQueryStates/
│   │   │   │               ├── dynamic/
│   │   │   │               │   └── [route]/
│   │   │   │               │       └── index.tsx
│   │   │   │               └── index.tsx
│   │   │   ├── tsconfig.json
│   │   │   └── turbo.json
│   │   ├── package.json
│   │   ├── react/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── specs/
│   │   │   │   ├── shared/
│   │   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   ├── referential-stability.spec.ts
│   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   ├── routing.spec.ts
│   │   │   │   │   ├── scroll.spec.ts
│   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   └── stitching.spec.ts
│   │   │   │   └── shared.spec.ts
│   │   │   ├── src/
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── main.tsx
│   │   │   │   ├── routes/
│   │   │   │   │   ├── basic-io.useQueryState.tsx
│   │   │   │   │   ├── basic-io.useQueryStates.tsx
│   │   │   │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │   │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │   │   │   ├── form.useQueryState.tsx
│   │   │   │   │   ├── form.useQueryStates.tsx
│   │   │   │   │   ├── hash-preservation.tsx
│   │   │   │   │   ├── history-sync.tsx
│   │   │   │   │   ├── json.tsx
│   │   │   │   │   ├── key-isolation.useQueryState.tsx
│   │   │   │   │   ├── key-isolation.useQueryStates.tsx
│   │   │   │   │   ├── life-and-death.tsx
│   │   │   │   │   ├── linking.useQueryState.other.tsx
│   │   │   │   │   ├── linking.useQueryState.tsx
│   │   │   │   │   ├── linking.useQueryStates.other.tsx
│   │   │   │   │   ├── linking.useQueryStates.tsx
│   │   │   │   │   ├── native-array.tsx
│   │   │   │   │   ├── pretty-urls.tsx
│   │   │   │   │   ├── push.useQueryState.tsx
│   │   │   │   │   ├── push.useQueryStates.tsx
│   │   │   │   │   ├── rate-limits.tsx
│   │   │   │   │   ├── referential-stability.useQueryState.tsx
│   │   │   │   │   ├── referential-stability.useQueryStates.tsx
│   │   │   │   │   ├── render-count.tsx
│   │   │   │   │   ├── repro-1099.useQueryState.tsx
│   │   │   │   │   ├── repro-1099.useQueryStates.tsx
│   │   │   │   │   ├── repro-1365.tsx
│   │   │   │   │   ├── repro-359.tsx
│   │   │   │   │   ├── repro-982.tsx
│   │   │   │   │   ├── routing.useQueryState.other.tsx
│   │   │   │   │   ├── routing.useQueryState.tsx
│   │   │   │   │   ├── routing.useQueryStates.other.tsx
│   │   │   │   │   ├── routing.useQueryStates.tsx
│   │   │   │   │   ├── scroll.tsx
│   │   │   │   │   ├── shallow.useQueryState.tsx
│   │   │   │   │   ├── shallow.useQueryStates.tsx
│   │   │   │   │   └── stitching.tsx
│   │   │   │   ├── routes.tsx
│   │   │   │   └── vite-env.d.ts
│   │   │   ├── tsconfig.app.json
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   ├── turbo.json
│   │   │   └── vite.config.ts
│   │   ├── react-router/
│   │   │   ├── package.json
│   │   │   ├── v5/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── README.md
│   │   │   │   ├── index.html
│   │   │   │   ├── package.json
│   │   │   │   ├── playwright.config.ts
│   │   │   │   ├── specs/
│   │   │   │   │   ├── shared/
│   │   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   │   └── stitching.spec.ts
│   │   │   │   │   └── shared.spec.ts
│   │   │   │   ├── src/
│   │   │   │   │   ├── adapter.ts
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── main.tsx
│   │   │   │   │   ├── react-router.tsx
│   │   │   │   │   ├── routes/
│   │   │   │   │   │   ├── basic-io.useQueryState.tsx
│   │   │   │   │   │   ├── basic-io.useQueryStates.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │   │   │   │   ├── fog-of-war._index.tsx
│   │   │   │   │   │   ├── fog-of-war.result.tsx
│   │   │   │   │   │   ├── form.useQueryState.tsx
│   │   │   │   │   │   ├── form.useQueryStates.tsx
│   │   │   │   │   │   ├── hash-preservation.tsx
│   │   │   │   │   │   ├── history-sync.tsx
│   │   │   │   │   │   ├── json.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryState.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryStates.tsx
│   │   │   │   │   │   ├── life-and-death.tsx
│   │   │   │   │   │   ├── linking.useQueryState.other.tsx
│   │   │   │   │   │   ├── linking.useQueryState.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.other.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.tsx
│   │   │   │   │   │   ├── native-array.tsx
│   │   │   │   │   │   ├── pretty-urls.tsx
│   │   │   │   │   │   ├── push.useQueryState.tsx
│   │   │   │   │   │   ├── push.useQueryStates.tsx
│   │   │   │   │   │   ├── rate-limits.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryState.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryStates.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryState.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryStates.tsx
│   │   │   │   │   │   ├── repro-359.tsx
│   │   │   │   │   │   ├── repro-982.tsx
│   │   │   │   │   │   ├── routing.useQueryState.other.tsx
│   │   │   │   │   │   ├── routing.useQueryState.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.other.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.tsx
│   │   │   │   │   │   ├── scroll.tsx
│   │   │   │   │   │   └── stitching.tsx
│   │   │   │   │   └── vite-env.d.ts
│   │   │   │   ├── tsconfig.app.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── tsconfig.node.json
│   │   │   │   ├── turbo.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── v6/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── README.md
│   │   │   │   ├── index.html
│   │   │   │   ├── package.json
│   │   │   │   ├── playwright.config.ts
│   │   │   │   ├── specs/
│   │   │   │   │   ├── repro-839.spec.ts
│   │   │   │   │   ├── shared/
│   │   │   │   │   │   ├── debounce.spec.ts
│   │   │   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   │   │   ├── loader.spec.ts
│   │   │   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   │   └── stitching.spec.ts
│   │   │   │   │   └── shared.spec.ts
│   │   │   │   ├── src/
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── main.tsx
│   │   │   │   │   ├── react-router.tsx
│   │   │   │   │   ├── routes/
│   │   │   │   │   │   ├── basic-io.useQueryState.tsx
│   │   │   │   │   │   ├── basic-io.useQueryStates.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │   │   │   │   ├── debounce.other.tsx
│   │   │   │   │   │   ├── debounce.tsx
│   │   │   │   │   │   ├── dynamic-segments.catch-all.$.tsx
│   │   │   │   │   │   ├── dynamic-segments.dynamic.$segment.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryState.end.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryState.start.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryStates.end.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryStates.start.tsx
│   │   │   │   │   │   ├── fog-of-war._index.tsx
│   │   │   │   │   │   ├── fog-of-war.result.tsx
│   │   │   │   │   │   ├── form.useQueryState.tsx
│   │   │   │   │   │   ├── form.useQueryStates.tsx
│   │   │   │   │   │   ├── hash-preservation.tsx
│   │   │   │   │   │   ├── history-sync.tsx
│   │   │   │   │   │   ├── json.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryState.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryStates.tsx
│   │   │   │   │   │   ├── life-and-death.tsx
│   │   │   │   │   │   ├── linking.useQueryState.other.tsx
│   │   │   │   │   │   ├── linking.useQueryState.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.other.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.tsx
│   │   │   │   │   │   ├── loader.tsx
│   │   │   │   │   │   ├── native-array.tsx
│   │   │   │   │   │   ├── popstate-queue-reset.other.tsx
│   │   │   │   │   │   ├── popstate-queue-reset.tsx
│   │   │   │   │   │   ├── pretty-urls.tsx
│   │   │   │   │   │   ├── push.useQueryState.tsx
│   │   │   │   │   │   ├── push.useQueryStates.tsx
│   │   │   │   │   │   ├── rate-limits.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryState.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryStates.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryState.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryStates.tsx
│   │   │   │   │   │   ├── repro-1293.a.tsx
│   │   │   │   │   │   ├── repro-1293.b.tsx
│   │   │   │   │   │   ├── repro-1365.tsx
│   │   │   │   │   │   ├── repro-359.tsx
│   │   │   │   │   │   ├── repro-839.tsx
│   │   │   │   │   │   ├── repro-982.tsx
│   │   │   │   │   │   ├── routing.useQueryState.other.tsx
│   │   │   │   │   │   ├── routing.useQueryState.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.other.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.tsx
│   │   │   │   │   │   ├── scroll.tsx
│   │   │   │   │   │   ├── shallow.useQueryState.tsx
│   │   │   │   │   │   ├── shallow.useQueryStates.tsx
│   │   │   │   │   │   └── stitching.tsx
│   │   │   │   │   └── vite-env.d.ts
│   │   │   │   ├── tsconfig.app.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── tsconfig.node.json
│   │   │   │   ├── turbo.json
│   │   │   │   └── vite.config.ts
│   │   │   └── v7/
│   │   │       ├── .gitignore
│   │   │       ├── README.md
│   │   │       ├── app/
│   │   │       │   ├── layout.tsx
│   │   │       │   ├── root.tsx
│   │   │       │   ├── routes/
│   │   │       │   │   ├── basic-io.useQueryState.tsx
│   │   │       │   │   ├── basic-io.useQueryStates.tsx
│   │   │       │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │       │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │       │   │   ├── debounce.other.tsx
│   │   │       │   │   ├── debounce.tsx
│   │   │       │   │   ├── dynamic-segments.catch-all.$.tsx
│   │   │       │   │   ├── dynamic-segments.dynamic.$segment.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryState.end.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryState.start.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryStates.end.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryStates.start.tsx
│   │   │       │   │   ├── fog-of-war._index.tsx
│   │   │       │   │   ├── fog-of-war.result.tsx
│   │   │       │   │   ├── form.useQueryState.tsx
│   │   │       │   │   ├── form.useQueryStates.tsx
│   │   │       │   │   ├── hash-preservation.tsx
│   │   │       │   │   ├── history-sync.tsx
│   │   │       │   │   ├── json.tsx
│   │   │       │   │   ├── key-isolation.useQueryState.tsx
│   │   │       │   │   ├── key-isolation.useQueryStates.tsx
│   │   │       │   │   ├── life-and-death.tsx
│   │   │       │   │   ├── linking.useQueryState.other.tsx
│   │   │       │   │   ├── linking.useQueryState.tsx
│   │   │       │   │   ├── linking.useQueryStates.other.tsx
│   │   │       │   │   ├── linking.useQueryStates.tsx
│   │   │       │   │   ├── loader.tsx
│   │   │       │   │   ├── native-array.tsx
│   │   │       │   │   ├── popstate-queue-reset.other.tsx
│   │   │       │   │   ├── popstate-queue-reset.tsx
│   │   │       │   │   ├── pretty-urls.tsx
│   │   │       │   │   ├── push.useQueryState.tsx
│   │   │       │   │   ├── push.useQueryStates.tsx
│   │   │       │   │   ├── rate-limits.tsx
│   │   │       │   │   ├── referential-stability.useQueryState.tsx
│   │   │       │   │   ├── referential-stability.useQueryStates.tsx
│   │   │       │   │   ├── render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
│   │   │       │   │   ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │       │   │   ├── render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
│   │   │       │   │   ├── repro-1099.useQueryState.tsx
│   │   │       │   │   ├── repro-1099.useQueryStates.tsx
│   │   │       │   │   ├── repro-1293.a.tsx
│   │   │       │   │   ├── repro-1293.b.tsx
│   │   │       │   │   ├── repro-1365.tsx
│   │   │       │   │   ├── repro-359.tsx
│   │   │       │   │   ├── repro-839.tsx
│   │   │       │   │   ├── repro-982.tsx
│   │   │       │   │   ├── routing.useQueryState.other.tsx
│   │   │       │   │   ├── routing.useQueryState.tsx
│   │   │       │   │   ├── routing.useQueryStates.other.tsx
│   │   │       │   │   ├── routing.useQueryStates.tsx
│   │   │       │   │   ├── scroll.tsx
│   │   │       │   │   ├── shallow.useQueryState.tsx
│   │   │       │   │   ├── shallow.useQueryStates.tsx
│   │   │       │   │   └── stitching.tsx
│   │   │       │   └── routes.ts
│   │   │       ├── package.json
│   │   │       ├── playwright.config.ts
│   │   │       ├── react-router.config.ts
│   │   │       ├── server.mjs
│   │   │       ├── specs/
│   │   │       │   ├── repro-839.spec.ts
│   │   │       │   ├── shared/
│   │   │       │   │   ├── debounce.spec.ts
│   │   │       │   │   ├── dynamic-segments.spec.ts
│   │   │       │   │   ├── flush-after-navigate.spec.ts
│   │   │       │   │   ├── fog-of-war.spec.ts
│   │   │       │   │   ├── key-isolation.spec.ts
│   │   │       │   │   ├── loader.spec.ts
│   │   │       │   │   ├── popstate-queue-reset.spec.ts
│   │   │       │   │   ├── push.spec.ts
│   │   │       │   │   ├── render-count.spec.ts
│   │   │       │   │   ├── repro-1099.spec.ts
│   │   │       │   │   ├── repro-1293.spec.ts
│   │   │       │   │   ├── repro-1365.spec.ts
│   │   │       │   │   ├── repro-359.spec.ts
│   │   │       │   │   ├── repro-982.spec.ts
│   │   │       │   │   ├── shallow.spec.ts
│   │   │       │   │   └── stitching.spec.ts
│   │   │       │   └── shared.spec.ts
│   │   │       ├── tsconfig.json
│   │   │       ├── turbo.json
│   │   │       └── vite.config.ts
│   │   ├── remix/
│   │   │   ├── .eslintrc.cjs
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── app/
│   │   │   │   ├── entry.client.tsx
│   │   │   │   ├── entry.server.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── root.tsx
│   │   │   │   └── routes/
│   │   │   │       ├── basic-io.useQueryState.tsx
│   │   │   │       ├── basic-io.useQueryStates.tsx
│   │   │   │       ├── conditional-rendering.useQueryState.tsx
│   │   │   │       ├── conditional-rendering.useQueryStates.tsx
│   │   │   │       ├── debounce-other.tsx
│   │   │   │       ├── debounce.tsx
│   │   │   │       ├── dynamic-segments.catch-all.$.tsx
│   │   │   │       ├── dynamic-segments.dynamic.$segment.tsx
│   │   │   │       ├── flush-after-navigate.useQueryState.end.tsx
│   │   │   │       ├── flush-after-navigate.useQueryState.start.tsx
│   │   │   │       ├── flush-after-navigate.useQueryStates.end.tsx
│   │   │   │       ├── flush-after-navigate.useQueryStates.start.tsx
│   │   │   │       ├── fog-of-war._index.tsx
│   │   │   │       ├── fog-of-war.result.tsx
│   │   │   │       ├── form.useQueryState.tsx
│   │   │   │       ├── form.useQueryStates.tsx
│   │   │   │       ├── hash-preservation.tsx
│   │   │   │       ├── history-sync.tsx
│   │   │   │       ├── json.tsx
│   │   │   │       ├── key-isolation.useQueryState.tsx
│   │   │   │       ├── key-isolation.useQueryStates.tsx
│   │   │   │       ├── life-and-death.tsx
│   │   │   │       ├── linking.useQueryState.other.tsx
│   │   │   │       ├── linking.useQueryState.tsx
│   │   │   │       ├── linking.useQueryStates.other.tsx
│   │   │   │       ├── linking.useQueryStates.tsx
│   │   │   │       ├── loader.tsx
│   │   │   │       ├── native-array.tsx
│   │   │   │       ├── popstate-queue-reset-other.tsx
│   │   │   │       ├── popstate-queue-reset.tsx
│   │   │   │       ├── pretty-urls.tsx
│   │   │   │       ├── push.useQueryState.tsx
│   │   │   │       ├── push.useQueryStates.tsx
│   │   │   │       ├── rate-limits.tsx
│   │   │   │       ├── referential-stability.useQueryState.tsx
│   │   │   │       ├── referential-stability.useQueryStates.tsx
│   │   │   │       ├── render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
│   │   │   │       ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │   │       ├── render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
│   │   │   │       ├── repro-1099.useQueryState.tsx
│   │   │   │       ├── repro-1099.useQueryStates.tsx
│   │   │   │       ├── repro-1293.a.tsx
│   │   │   │       ├── repro-1293.b.tsx
│   │   │   │       ├── repro-1365.tsx
│   │   │   │       ├── repro-359.tsx
│   │   │   │       ├── repro-839.tsx
│   │   │   │       ├── repro-982.tsx
│   │   │   │       ├── routing.useQueryState.other.tsx
│   │   │   │       ├── routing.useQueryState.tsx
│   │   │   │       ├── routing.useQueryStates.other.tsx
│   │   │   │       ├── routing.useQueryStates.tsx
│   │   │   │       ├── scroll.tsx
│   │   │   │       ├── shallow.useQueryState.tsx
│   │   │   │       ├── shallow.useQueryStates.tsx
│   │   │   │       └── stitching.tsx
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── specs/
│   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   ├── repro-839.spec.ts
│   │   │   │   ├── shared/
│   │   │   │   │   ├── debounce.spec.ts
│   │   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   │   ├── loader.spec.ts
│   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   └── stitching.spec.ts
│   │   │   │   └── shared.spec.ts
│   │   │   ├── tsconfig.json
│   │   │   ├── turbo.json
│   │   │   └── vite.config.ts
│   │   ├── shared/
│   │   │   ├── components/
│   │   │   │   ├── display.tsx
│   │   │   │   ├── hydration-marker.tsx
│   │   │   │   ├── link.tsx
│   │   │   │   ├── null-detector.tsx
│   │   │   │   └── router.tsx
│   │   │   ├── define-test.ts
│   │   │   ├── lib/
│   │   │   │   └── options.ts
│   │   │   ├── package.json
│   │   │   ├── playwright/
│   │   │   │   ├── agent-reporter.ts
│   │   │   │   ├── expect-url.ts
│   │   │   │   ├── log-spy.ts
│   │   │   │   ├── navigate.ts
│   │   │   │   ├── reporter.ts
│   │   │   │   └── url-spy.ts
│   │   │   ├── playwright.config.ts
│   │   │   ├── shared.spec.ts
│   │   │   ├── specs/
│   │   │   │   ├── basic-io.spec.ts
│   │   │   │   ├── basic-io.tsx
│   │   │   │   ├── conditional-rendering.spec.ts
│   │   │   │   ├── conditional-rendering.tsx
│   │   │   │   ├── debounce-client.tsx
│   │   │   │   ├── debounce-server.tsx
│   │   │   │   ├── debounce.defs.ts
│   │   │   │   ├── debounce.spec.ts
│   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   ├── dynamic-segments.tsx
│   │   │   │   ├── flush-after-navigate.defs.ts
│   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   ├── flush-after-navigate.tsx
│   │   │   │   ├── form.spec.ts
│   │   │   │   ├── form.tsx
│   │   │   │   ├── hash-preservation.spec.ts
│   │   │   │   ├── hash-preservation.tsx
│   │   │   │   ├── history-sync.spec.ts
│   │   │   │   ├── history-sync.tsx
│   │   │   │   ├── json.spec.ts
│   │   │   │   ├── json.tsx
│   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   ├── key-isolation.tsx
│   │   │   │   ├── life-and-death.spec.ts
│   │   │   │   ├── life-and-death.tsx
│   │   │   │   ├── linking.spec.ts
│   │   │   │   ├── linking.tsx
│   │   │   │   ├── loader.spec.ts
│   │   │   │   ├── loader.tsx
│   │   │   │   ├── native-array.spec.ts
│   │   │   │   ├── native-array.tsx
│   │   │   │   ├── popstate-queue-reset.defs.ts
│   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   ├── popstate-queue-reset.tsx
│   │   │   │   ├── pretty-urls.spec.ts
│   │   │   │   ├── pretty-urls.tsx
│   │   │   │   ├── push.spec.ts
│   │   │   │   ├── push.tsx
│   │   │   │   ├── rate-limits.tsx
│   │   │   │   ├── react-router/
│   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   ├── fog-of-war.tsx
│   │   │   │   │   ├── repro-839-location-state-persistence.spec.ts
│   │   │   │   │   └── repro-839-location-state-persistence.tsx
│   │   │   │   ├── referential-stability.spec.ts
│   │   │   │   ├── referential-stability.tsx
│   │   │   │   ├── render-count.params.ts
│   │   │   │   ├── render-count.spec.ts
│   │   │   │   ├── render-count.tsx
│   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   ├── repro-1099.tsx
│   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   ├── repro-1293.tsx
│   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   ├── repro-1365.tsx
│   │   │   │   ├── repro-359.spec.ts
│   │   │   │   ├── repro-359.tsx
│   │   │   │   ├── repro-982.spec.ts
│   │   │   │   ├── repro-982.tsx
│   │   │   │   ├── routing.defs.ts
│   │   │   │   ├── routing.spec.ts
│   │   │   │   ├── routing.tsx
│   │   │   │   ├── scroll.spec.ts
│   │   │   │   ├── scroll.tsx
│   │   │   │   ├── shallow.spec.ts
│   │   │   │   ├── shallow.tsx
│   │   │   │   ├── stitching.defs.ts
│   │   │   │   ├── stitching.spec.ts
│   │   │   │   └── stitching.tsx
│   │   │   └── tsconfig.json
│   │   └── tanstack-router/
│   │       ├── .cta.json
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── index.html
│   │       ├── package.json
│   │       ├── playwright.config.ts
│   │       ├── specs/
│   │       │   ├── shared/
│   │       │   │   ├── basic-io.spec.ts
│   │       │   │   ├── conditional-rendering.spec.ts
│   │       │   │   ├── form.spec.ts
│   │       │   │   ├── hash-preservation.spec.ts
│   │       │   │   ├── json.spec.ts
│   │       │   │   ├── key-isolation.spec.ts
│   │       │   │   ├── linking.spec.ts
│   │       │   │   ├── native-array.spec.ts
│   │       │   │   ├── pretty-urls.spec.ts
│   │       │   │   ├── push.spec.ts
│   │       │   │   ├── referential-stability.spec.ts
│   │       │   │   ├── repro-1099.spec.ts
│   │       │   │   ├── repro-1365.spec.ts
│   │       │   │   ├── routing.spec.ts
│   │       │   │   ├── scroll.spec.ts
│   │       │   │   └── shallow.spec.ts
│   │       │   ├── shared.spec.ts
│   │       │   └── trailing-slash.spec.ts
│   │       ├── src/
│   │       │   ├── layout.tsx
│   │       │   ├── main.tsx
│   │       │   └── routes/
│   │       │       ├── __root.tsx
│   │       │       ├── basic-io.useQueryState.tsx
│   │       │       ├── basic-io.useQueryStates.tsx
│   │       │       ├── conditional-rendering.useQueryState.tsx
│   │       │       ├── conditional-rendering.useQueryStates.tsx
│   │       │       ├── form.useQueryState.tsx
│   │       │       ├── form.useQueryStates.tsx
│   │       │       ├── hash-preservation.tsx
│   │       │       ├── history-sync.tsx
│   │       │       ├── json.tsx
│   │       │       ├── key-isolation.useQueryState.tsx
│   │       │       ├── key-isolation.useQueryStates.tsx
│   │       │       ├── life-and-death.tsx
│   │       │       ├── linking.useQueryState.other.tsx
│   │       │       ├── linking.useQueryState.tsx
│   │       │       ├── linking.useQueryStates.other.tsx
│   │       │       ├── linking.useQueryStates.tsx
│   │       │       ├── native-array.tsx
│   │       │       ├── pretty-urls.tsx
│   │       │       ├── push.useQueryState.tsx
│   │       │       ├── push.useQueryStates.tsx
│   │       │       ├── referential-stability.useQueryState.tsx
│   │       │       ├── referential-stability.useQueryStates.tsx
│   │       │       ├── repro-1099.useQueryState.tsx
│   │       │       ├── repro-1099.useQueryStates.tsx
│   │       │       ├── repro-1365.tsx
│   │       │       ├── routing.useQueryState.other.tsx
│   │       │       ├── routing.useQueryState.tsx
│   │       │       ├── routing.useQueryStates.other.tsx
│   │       │       ├── routing.useQueryStates.tsx
│   │       │       ├── scroll.tsx
│   │       │       ├── shallow.useQueryState.tsx
│   │       │       ├── shallow.useQueryStates.tsx
│   │       │       └── trailing-slash.tsx
│   │       ├── tsconfig.json
│   │       ├── turbo.json
│   │       └── vite.config.js
│   ├── examples/
│   │   ├── next-app/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── next.config.ts
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── app/
│   │   │   │   │   ├── _components/
│   │   │   │   │   │   ├── filter.tsx
│   │   │   │   │   │   ├── pagination.tsx
│   │   │   │   │   │   └── users-list.tsx
│   │   │   │   │   ├── globals.css
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── searchParams.tsx
│   │   │   │   └── data.ts
│   │   │   └── tsconfig.json
│   │   ├── package.json
│   │   └── trpc/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── app/
│   │       │   ├── components/
│   │       │   │   ├── inverted-coordinates.tsx
│   │       │   │   └── random-coordinates.tsx
│   │       │   ├── root.tsx
│   │       │   ├── routes/
│   │       │   │   ├── api/
│   │       │   │   │   └── trpc.ts
│   │       │   │   └── index.tsx
│   │       │   ├── routes.ts
│   │       │   ├── search-params.ts
│   │       │   ├── server/
│   │       │   │   └── trpc.ts
│   │       │   └── utils/
│   │       │       └── trpc.ts
│   │       ├── package.json
│   │       ├── react-router.config.ts
│   │       ├── server.mjs
│   │       ├── tsconfig.json
│   │       └── vite.config.ts
│   ├── nuqs/
│   │   ├── .gitignore
│   │   ├── adapters/
│   │   │   ├── custom.d.ts
│   │   │   ├── next/
│   │   │   │   ├── app.d.ts
│   │   │   │   └── pages.d.ts
│   │   │   ├── next.d.ts
│   │   │   ├── react-router/
│   │   │   │   ├── v6.d.ts
│   │   │   │   └── v7.d.ts
│   │   │   ├── react-router.d.ts
│   │   │   ├── react.d.ts
│   │   │   ├── remix.d.ts
│   │   │   ├── tanstack-router.d.ts
│   │   │   └── testing.d.ts
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── prepack.sh
│   │   ├── server.d.ts
│   │   ├── src/
│   │   │   ├── adapters/
│   │   │   │   ├── custom.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── defs.ts
│   │   │   │   │   ├── key-isolation.ts
│   │   │   │   │   ├── patch-history.browser.test.ts
│   │   │   │   │   ├── patch-history.ts
│   │   │   │   │   └── react-router.ts
│   │   │   │   ├── next/
│   │   │   │   │   ├── app.ts
│   │   │   │   │   ├── impl.app.ts
│   │   │   │   │   ├── impl.pages.test.ts
│   │   │   │   │   ├── impl.pages.ts
│   │   │   │   │   └── pages.ts
│   │   │   │   ├── next.ts
│   │   │   │   ├── react-router/
│   │   │   │   │   ├── v6.ts
│   │   │   │   │   └── v7.ts
│   │   │   │   ├── react-router.ts
│   │   │   │   ├── react.ts
│   │   │   │   ├── remix.ts
│   │   │   │   ├── tanstack-router.ts
│   │   │   │   └── testing.ts
│   │   │   ├── api.test.ts
│   │   │   ├── cache.test.ts
│   │   │   ├── cache.ts
│   │   │   ├── defs.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── lib/
│   │   │   │   ├── compare.test.ts
│   │   │   │   ├── compare.ts
│   │   │   │   ├── compose.test.ts
│   │   │   │   ├── compose.ts
│   │   │   │   ├── debug.test.ts
│   │   │   │   ├── debug.ts
│   │   │   │   ├── emitter.test.ts
│   │   │   │   ├── emitter.ts
│   │   │   │   ├── errors.ts
│   │   │   │   ├── queues/
│   │   │   │   │   ├── debounce.test.ts
│   │   │   │   │   ├── debounce.ts
│   │   │   │   │   ├── rate-limiting.ts
│   │   │   │   │   ├── reset.ts
│   │   │   │   │   ├── throttle.test.ts
│   │   │   │   │   ├── throttle.ts
│   │   │   │   │   ├── useSyncExternalStores.browser.test.ts
│   │   │   │   │   └── useSyncExternalStores.ts
│   │   │   │   ├── safe-parse.ts
│   │   │   │   ├── search-params.ts
│   │   │   │   ├── sync.browser.test.tsx
│   │   │   │   ├── sync.ts
│   │   │   │   ├── timeout.test.ts
│   │   │   │   ├── timeout.ts
│   │   │   │   ├── url-encoding.browser.test.ts
│   │   │   │   ├── url-encoding.ts
│   │   │   │   ├── with-resolvers.test.ts
│   │   │   │   └── with-resolvers.ts
│   │   │   ├── loader.test.ts
│   │   │   ├── loader.ts
│   │   │   ├── parsers.test.ts
│   │   │   ├── parsers.ts
│   │   │   ├── serializer.test.ts
│   │   │   ├── serializer.ts
│   │   │   ├── standard-schema.test.ts
│   │   │   ├── standard-schema.ts
│   │   │   ├── testing.ts
│   │   │   ├── useQueryState.browser.test.tsx
│   │   │   ├── useQueryState.ts
│   │   │   ├── useQueryStates.browser.test.tsx
│   │   │   └── useQueryStates.ts
│   │   ├── testing.d.ts
│   │   ├── tests/
│   │   │   ├── cache.test-d.ts
│   │   │   ├── components/
│   │   │   │   └── repro-1099.tsx
│   │   │   ├── parsers.test-d.ts
│   │   │   ├── serializer.test-d.ts
│   │   │   ├── useQueryState.test-d.ts
│   │   │   └── useQueryStates.test-d.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   ├── turbo.json
│   │   ├── vitest.browser.setup.ts
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.ts
│   ├── res/
│   │   └── package.json
│   └── scripts/
│       ├── next-release-analyser.ts
│       ├── package.json
│       ├── release-notes-automation.test.ts
│       ├── release-notes-automation.ts
│       └── tsconfig.json
├── pnpm-workspace.yaml
└── turbo.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .agents/docs/adapter-development.md
================================================
# Adapter Development

Guide for adding framework adapters to nuqs.

## Overview

Adapters wrap the app root and provide the minimal translation layer between nuqs and framework routing APIs.

- **Next.js app router:** `nuqs/adapters/next/app`
- **Next.js pages router:** `nuqs/adapters/next/pages`
- **React SPA:** `nuqs/adapters/react`
- **Remix:** `nuqs/adapters/remix`
- **React Router v6:** `nuqs/adapters/react-router/v6`
- **React Router v7:** `nuqs/adapters/react-router/v7`
- **TanStack Router:** `nuqs/adapters/tanstack-router`
- **Testing:** `nuqs/adapters/testing`

## Adding a New Framework Adapter

### Checklist

1. **Mirror existing adapter API surface**
   - Ensure the exported provider component matches established patterns
   - Use consistent naming and parameter shapes

2. **Implement minimal feature parity**
   - Read/query: Parse current search params
   - Push/replace history: Update URL without full reload
   - Batching: Support merging multiple updates per tick

3. **Create e2e bench**
   - Add test application under `packages/e2e/<framework>`
   - Cover both App Router and Pages Router if applicable

4. **Documentation**
   - Update README Adapters section
   - Add docs content page explaining adapter setup

5. **Test coverage**
   - Unit tests for adapter integration
   - E2E tests for framework-specific behaviors

### Key Requirements

- Adapter must support `shallow` option semantics (when applicable to framework)
- Handle history `push` vs `replace` operations correctly
- Ensure batch queue integrity (updates per key merged while preserving final state)
- No memory leaks (listeners removed on unmount)

### Server-Side Utilities

When adding adapter support, consider server utilities:

- **Loader:** `createLoader(parsers[, { urlKeys }])` for one-off parsing
- **Cache:** `createSearchParamsCache(parsers)` for nested Server Components (Next.js app router)
- **Serializer:** `createSerializer(parsers[, { urlKeys }])` for canonical URLs / links
- Import server helpers from `'nuqs/server'` (avoids the `"use client"` directive)

These should work identically across adapters where applicable.

## Options Semantics

When implementing adapter support:

- **`history`:** `'replace'` (default) or `'push'`
- **`shallow`** (Next.js only): Default true (client-first). Set false to trigger RSC / SSR invalidation
- **`throttleMs`:** ≥50ms (ignored if lower). Only URL & server notification are throttled, not in-memory state
- **`startTransition`:** Pass from `React.useTransition` when using `shallow: false` for loading states

Override per-update via second argument to setter: `setValue(v, { history, shallow, throttleMs })`

## Architectural Flow

1. Hook reads initial value from current `window.location.search`
2. Local React state mirrors parsed value
3. Setter enqueues mutation intent (key → serialized value | delete)
4. Batch flush (throttled) applies merged changes to History API (push/replace)
5. Promise resolves with updated `URLSearchParams`
6. If `shallow: false`: uses router APIs to trigger server-side rendering / data fetching

## Extensibility

- Prefer composition (wrapping adapter) over modifying core adapter
- Keep adapter interfaces thin (translate framework navigation to common history operations)
- Avoid duplicating logic across adapters (prefer shared utility)


================================================
FILE: .agents/docs/api-design.md
================================================
# API Design & Architecture

Guide for maintaining API stability, designing extensions, and understanding the architecture.

## Core Architecture

### Flow

1. **Initialization:** Hook reads initial value from current `window.location.search`
2. **Local State:** React state mirrors parsed value
3. **Mutation Enqueue:** Setter enqueues mutation intent (key → serialized value | delete)
4. **Batch & Throttle:** Multiple `setState` calls in one tick are merged
5. **Flush to URL:** Batch flush (throttled ≥50ms) applies merged changes to History API (push/replace)
6. **Promise Resolution:** Returns when URL update flushes; cache per batch
7. **Server Trigger:** If `shallow: false`, uses router APIs to trigger server-side rendering / data fetching

### Batch Queue Integrity

- **Key merging:** Updates for the same key within one tick are coalesced (final state wins)
- **Final value preservation:** Last write for each key determines the output
- **No reordering:** Order of keys in URL is stable

## Design Principles

### 1. URL as Single Source of Truth

- URL shape defines state shape
- Parsing must be deterministic
- Serialization must be lossless

### 2. Type Safety

- Hooks return typed values matching parser output
- Builder chaining preserves types
- Type exports are part of public API

### 3. Zero Dependencies & Bundle Size

- No external dependencies
- Avoid side effects in module top-level (affects tree shaking)
- Keep parse/serialize fast and lightweight
- Throwing in parsers has bundle cost (return `null` instead)

### 4. Backward Compatibility

Before modifying core logic in `packages/nuqs`:

1. **Assess API surface impact**
   - Type exports
   - Builder chaining
   - Hook signatures

2. **Maintain backward compatibility** unless intentional breaking change
   - Breaking changes require justification
   - Provide migration notes in PR body

3. **Validate types** with `pnpm test --filter nuqs` (includes TS type tests)

## Performance & Reliability

### Batch Efficiency

- Merging updates per key while preserving final state
- Single URL write per flush cycle
- No synchronous expensive operations inside parse/serialize

### Memory Management

- Ensure no memory leaks
- Remove listeners on unmount
- Clear event handler references

### URL Determinism

- Keep serialization deterministic
- Use stable ordering for multiple keys
- Consistent formatting

## Extensibility Guidelines

When extending nuqs:

### Composition Over Modification

- Prefer wrapping parsers over modifying core hook
- Create adapters for new frameworks instead of baking support in core
- Use builder pattern for optional behaviors

### Code Organization

- Add generic utilities under internal helpers module if reused ≥2 places
- Keep adapter interfaces thin
- Translate framework navigation to common history operations

### Builder Pattern

- Use `.withDefault()` for defaults
- Use `.withOptions()` for behavior customization
- Keep chaining lightweight

## Safety Checklist for Core Changes

Do not:

- Introduce side effects in module top-level (tree shaking impact)
- Use non-standard browser APIs without guards
- Increase bundle size significantly (maintain zero dependencies)
- Export internal implementation details
- Break existing type signatures

Do:

- Test types with type-level tests (`.test-d.ts`)
- Provide type exports alongside implementation
- Document API changes in README
- Validate with full test suite


================================================
FILE: .agents/docs/git-workflow.md
================================================
# Release & Git Workflow

Guide for versioning, commits, pull requests, and release process.

## Conventional Commits

All commits follow the Conventional Commits specification. This is enforced by review.

### Format

```
<type>(<scope>): <subject>

<body>

<footer>
```

### Commit Types

- **`feat:`** New feature
- **`fix:`** Bug fix
- **`perf:`** Performance improvement
- **`docs:`** Documentation only
- **`refactor:`** Code restructuring (no feature change)
- **`test:`** Test addition or update
- **`chore:`** Tooling, dependencies, config

### Breaking Changes

For breaking changes:

1. Use `feat!:` or `fix!:` prefix
2. Add footer: `BREAKING CHANGE: <description>`

Example:

```
feat!: change parser return type

BREAKING CHANGE: parseAsInteger now throws on invalid input instead of returning null
```

## Semantic Versioning

Version bumping is **automated by `semantic-release`**:

- **Patch** (v1.2.3 → v1.2.4) — `fix:` commits
- **Minor** (v1.2.0 → v1.3.0) — `feat:` commits
- **Major** (v1.0.0 → v2.0.0) — `feat!:` or `fix!:` (breaking changes)

**Do not manually bump versions** — The automation handles this.

## Release Branch

- **Release branch:** `next`
- Commits to `next` trigger `semantic-release`
- Publishing to NPM is automatic
- Check [GitHub Releases](../../releases) for version history

## Pull Request Standards

### Before Opening a PR

1. Ensure commit messages follow Conventional Commits
2. Run local tests: `pnpm test`
3. Verify types with type-level tests
4. Update documentation if applicable
5. Consider if breaking change justification is needed

### PR Description

Include:

- **Summary** — What is this PR doing and why?
- **Type** — Is this a feature, fix, refactor, or doc update?
- **Changes** — High-level list of modified areas
- **Testing** — What test coverage was added?
- **Breaking Changes** — If applicable, describe migration path

### PR Title

PR title should match the first commit message (Conventional Commit format):

- `feat: add new parser type`
- `fix: handle edge case in batching`
- `docs: update adapter setup guide`

### PR Checklist

Before marking ready for review:

- [ ] `pnpm test` passes locally
- [ ] Tests added/updated for new behavior
- [ ] All new exports documented
- [ ] Docs content updated if applicable
- [ ] README updated if user-facing change
- [ ] No unintended bundle size growth
- [ ] Conventional Commit message
- [ ] No unresolved TODOs introduced
- [ ] No stray console logs (except controlled debug)

## Documentation Updates

Update documentation when:

- **Public API surface changes** (new exports, hook signature)
- **Parser behavior changes** (parsing rules, serialization)
- **Adapter requirements change** (new options, breaking changes)

### What to Update

1. **README.md**
   - Examples section
   - API reference
   - Adapter list

2. **MDX docs** under `packages/docs/content`
   - Mirror relevant README sections
   - Add detailed examples
   - Document configuration options

### Documentation Best Practices

- Keep examples concise
- Link to existing demos instead of duplicating code
- Maintain consistency with existing documentation style
- Add examples that show common use cases
- Update table of contents if adding new sections

## Decision Log

When making non-trivial architectural changes:

1. Add a short note to AGENTS.md Decision Log section
2. Format: `YYYY-MM-DD - <Title> - Rationale / Impact / Migration (if any)`
3. Examples:
   - `2025-01-15 - Add batching optimization - Reduces URL updates by 40% when multiple state changes occur in same tick. No migration needed.`
   - `2025-01-20 - Parser requires eq method - Enables custom equality checks for complex types. Existing parsers automatically compatible.`

## Automation & Tools

The team uses the following automation:

- **Conventional Commits:** Enforced by commit linting
- **Type checking:** Part of `pnpm test`
- **semantic-release:** Automatic versioning and publishing from `next` branch
- **PR checks:** Linting, testing, type checking run automatically

**Agents may:**

- Generate parser boilerplate
- Update Adapters section in documentation
- Append PR checklist results
- Run local tests & lint before proposing changes

**Agents must not:**

- Auto-commit version bumps (handled by release automation)
- Force push to main/master
- Modify git configuration
- Skip git hooks


================================================
FILE: .agents/docs/parser-implementation.md
================================================
# Parser Implementation

Guide for creating custom parsers and understanding parser semantics.

## Overview

Parsers are the bridge between URL strings and typed state. Each parser provides bidirectional conversion.

## Creating a Custom Parser

### Core Interface

A parser has two methods:

- **`parse(query: string): T | null`** — Deserialize from URL string
- **`serialize(value: T): string`** — Serialize to URL string

Optionally:

- **`eq`** — Custom equality check (defaults to `===`)

### Implementation Checklist

1. **Implement `parse(query: string): T | null`**
   - Return `null` for invalid input (not throwing; smaller bundle impact)
   - Keep the function pure and fast

2. **Implement `serialize(value: T): string`**
   - Must be deterministic (stable output for same input)
   - Pure function, no side effects

3. **Wrap with `createParser`**
   - Enables chaining with `.withDefault()` and `.withOptions()`
   - Example: `export const parseAsInteger = createParser({ parse, serialize, eq })`

4. **Validate bijectivity**
   - Ensure `parse(serialize(v))` yields an equivalent value
   - Use the `isParserBijective` helper to verify
   - Round-trip tests are essential

5. **Add unit tests**
   - Valid inputs
   - Invalid inputs
   - Round-trip verification
   - Edge cases specific to your type

6. **Update documentation**
   - README Parsing section
   - MDX docs under `packages/docs/content`

7. **Consider server import path support**
   - Works identically when imported from `'nuqs/server'`
   - Use standard library functions only (no DOM APIs)

## Parser Design Principles

### Serialization Rules

- **Lossless:** Must preserve all information needed for valid round-trips
- **Pure:** Same input always produces same output
- **Deterministic:** Stable ordering when using multiple keys
- **No side effects:** Keep async operations out of parse/serialize

### Error Handling

- **Invalid parse:** Return `null`, not throw
  - Reduces bundle size impact
  - Allows graceful degradation
  - Simpler composition

- **Validation is optional:** Parsers do not validate semantic constraints
  - If you add validation helpers, keep them opt-in
  - Avoid coupling to heavy schema libs
  - Document integrations (e.g., Zod) externally

### Performance Considerations

- Keep parse/serialize as lightweight as possible
- Avoid expensive operations in these functions
- Remember they run synchronously on URL changes

## Builder Methods

### `.withDefault(value)`

Provides an internal default value. The default is **not written to the URL**.

```ts
const parser = parseAsInteger.withDefault(0)
// URL: ?count=    (empty or absent)
// State: 0        (from default)
```

### `.withOptions({ history, shallow, limitUrlUpdates, startTransition })`

Configure behavior options:

- **`history`:** `'push'` or `'replace'` (default)
- **`shallow`:** Trigger SSR/RSC invalidation (Next.js)
- **`limitUrlUpdates`:** Optional function to debounce updates
- **`startTransition`:** Pass from `useTransition` for loading states

## Anti-Patterns

Avoid:

- **Throwing for invalid input** — Return `null` instead
- **Lossy serialization** — Must preserve all information
- **Impure functions** — Same input must produce same output
- **Blocking async behavior** — No Promise-based parsing
- **Non-deterministic ordering** — Matters for URL length and caching

## Security & Validation

Parsers are primarily **type converters**, not validators. If you need validation:

- Keep validation helpers opt-in
- Document recommended external libraries (e.g., Zod, Standard Schema v1)
- Prefer composition over coupling to schema libraries

## Examples

See the parser test suite and README for concrete examples:

- `parseAsInteger` — Basic number parsing
- `parseAsString` — String identity
- `parseAsArrayOf()` — Generic array parsing
- Custom parsers in documentation


================================================
FILE: .agents/docs/quality-standards.md
================================================
# Quality Standards

Guide for performance, security, reliability, and quality assurance.

## Exit Conditions for Agent Tasks

A task is **DONE** when all of the following are satisfied:

- [ ] All checklist items satisfied
- [ ] Tests pass locally (`pnpm test`)
- [ ] Docs consistent with behavior
- [ ] No unresolved TODOs introduced
- [ ] No stray console logs (except controlled debug support)

## Performance Guidelines

### Bundle Size Constraints

- **Maintain zero dependencies** — Core library has no external deps
- **Avoid side effects in module top-level** — Affects tree shaking
- **Keep parse/serialize fast** — Called synchronously on every URL change
- **Avoid expensive operations** inside hooks (memoize if needed)

### Measuring Performance

For performance improvements:

1. Benchmark before/after
2. Include measurement methodology in PR
3. Document impact quantitatively
4. Validate with full test suite

### Batch Efficiency

- Merging updates per key preserves final state
- Single URL write per flush cycle (≥50ms throttle)
- No blocking operations during flush
- Listeners cleaned up on unmount (no leaks)

## Reliability Guidelines

### Memory Management

- **Remove listeners on unmount** — Prevents memory leaks
- **Clear event handler references** — Especially in cleanup phases
- **No circular references** — Between components and parsers
- **Test cleanup** — Verify unmounted components don't cause errors

### URL Determinism

- **Stable serialization** — Same input always produces same output
- **Consistent ordering** — Multiple keys serialize in predictable order
- **Deterministic parsing** — No randomness or side effects
- **Lossless round-trip** — `parse(serialize(v)) ≈ v` for all valid values

### Error Handling

When something goes wrong:

- **Parser invalid input:** Return `null`, not throw
  - Smaller bundle impact
  - Graceful degradation
  - Easier composition

- **Invalid state recovery:** Fall back to defaults gracefully
- **Type safety:** Prevent invalid states at type level

## Security Practices

### Parser Validation

Parsers are primarily **type converters**, not validators:

- Keep validation opt-in
- Avoid coupling to heavy validation libraries
- Document external integrations (Zod, Standard Schema v1)

### No User Input Injection

- Parse all URL params defensively
- Validate types before using
- Never interpolate user input into code/templates

### Safe Browser API Usage

- Guard non-standard browser APIs
- Check for availability before use
- Fallback to safe alternatives

## Anti-Patterns to Avoid

### In Parsers

- ❌ **Throwing for invalid input** — Return `null` instead
- ❌ **Lossy serialization** — Must preserve all information
- ❌ **Impure functions** — Same input must produce same output
- ❌ **Blocking async behavior** — No Promise-based parsing
- ❌ **Non-deterministic output** — Breaks URL length and caching

### In Hooks

- ❌ **Side effects in render** — Use useEffect properly
- ❌ **Synchronous expensive operations** — Defer to useCallback/useMemo
- ❌ **Memory leaks on unmount** — Always clean up
- ❌ **Infinite update loops** — Verify batch and throttle mechanics

### In Adapters

- ❌ **Duplicating logic across adapters** — Prefer shared utilities
- ❌ **Tight coupling to framework internals** — Use public APIs
- ❌ **Breaking API compatibility** — Keep surfaces aligned
- ❌ **Missing batch/throttle support** — Essential for all adapters

### In Core Library

- ❌ **Side effects in module top-level** — Breaks tree shaking
- ❌ **Non-standard browser APIs** — Without guards
- ❌ **Significant bundle growth** — Monitor size in PRs
- ❌ **Exporting internal implementation** — Only public interfaces

## Code Quality Checklist

For any change:

- [ ] Type-safe throughout
- [ ] Tests added or updated
- [ ] No console.log/debugger statements
- [ ] No dead code
- [ ] No duplicate logic
- [ ] Comments explain "why", not "what"
- [ ] Function names are clear
- [ ] Error messages are helpful

## Documentation Quality

For user-facing changes:

- [ ] README updated with examples
- [ ] API changes documented with types
- [ ] Migration guide (if breaking change)
- [ ] Examples runnable and up-to-date
- [ ] No typos or grammatical errors
- [ ] Consistent with existing docs style

## Type Safety

- [ ] All exports have explicit types
- [ ] Generic constraints are clear
- [ ] No `any` types unless justified
- [ ] Type tests included (`.test-d.ts`)
- [ ] Types match behavior
- [ ] Return types are specific (not `unknown`)

## Common Issues to Check

### Import Paths

- Verify relative imports resolve correctly
- Check that exports work from both CJS and ESM
- Ensure server utilities available from `'nuqs/server'`

### Framework Adapters

- Verify history API usage matches framework
- Check batch/throttle behavior aligns with core
- Test in actual framework (not just testing adapter)

### Type Coverage

- Run type tests: `pnpm test --filter nuqs`
- Verify exported types in `api.test.ts`
- Check builder chaining preserves types

## Debugging Checklist

Enable debug logs when investigating:

```js
localStorage.setItem('debug', 'nuqs')
```

Use prefixes:

- `[nuqs]` — Single-key hook operations
- `[nuq+]` — Multi-key hook operations

Capture debug output for:

- Issue reports
- Performance analysis
- State synchronization problems


================================================
FILE: .agents/docs/testing.md
================================================
# Testing Patterns

Guide for testing strategy, test organization, and regression workflows.

## Full Test Suite

Run the complete test pipeline:

```bash
pnpm test
```

This takes **5-10 minutes** and includes:

- Build (tsup)
- Unit tests
- Type-level tests
- End-to-end tests

Do not time out the full suite.

## Test Categories

### Unit Tests

**Where:** `packages/nuqs/tests/*.test.ts`

Test hooks with `NuqsTestingAdapter`:

```ts
import { NuqsTestingAdapter } from 'nuqs/adapters/testing'
import { renderHook, act } from '@testing-library/react'
```

Coverage:

- Parser logic (valid, invalid, round-trip)
- Hook behavior (state updates, URL sync)
- Batching and throttling
- Builder methods (`.withDefault()`, `.withOptions()`)

### Type-Level Tests

**Where:** `packages/nuqs/tests/*.test-d.ts`

Add type tests when updating type definitions:

```ts
import { expectType, expectAssignable } from 'tsd'
```

Coverage:

- Hook return types
- Parser generic constraints
- Builder result types
- Exported type shape

### API Tests

**Where:** `packages/nuqs/src/api.test.ts`

Check exported symbols when adding new exports:

```ts
// Verify API surface matches documentation
import * as api from 'nuqs'
```

Coverage:

- All public exports present
- No unintended exports

### End-to-End Tests

**Where:** `packages/e2e/*`

Test framework-specific adapter behaviors:

Framework targets:

- Next.js app router
- Next.js pages router
- React SPA
- Remix
- TanStack Router
- React Router v6/v7

Coverage:

- Initial page load with search params
- URL updates and state synchronization
- History push/replace
- Adapter-specific features (shallow, SSR)
- Frame/tab sync (where applicable)

## Regression Workflow

When fixing a bug:

1. **Reproduce with failing test first** (preferred)
   - Add test case demonstrating the bug
   - Test should fail before fix
   - Test passes after fix

2. **Fix the issue**
   - Minimal change to fix the specific problem
   - Preserve all other behavior

3. **Ensure types remain stable**
   - Run type-level tests
   - Check `api.test.ts`
   - Validate with full `pnpm test`

4. **Add scenario to e2e if framework-specific**
   - If the bug is adapter-related, add e2e coverage
   - Helps prevent regressions in that framework

## Common Testing Patterns

### Testing a Parser

```ts
describe('parseAsCustomType', () => {
  it('parses valid input', () => {
    expect(parseAsCustomType.parse('valid')).toEqual(expectedValue)
  })

  it('returns null for invalid input', () => {
    expect(parseAsCustomType.parse('invalid')).toBeNull()
  })

  it('round-trips correctly', () => {
    const value = {
      /* ... */
    }
    expect(parseAsCustomType.parse(parseAsCustomType.serialize(value))).toEqual(
      value
    )
  })
})
```

### Testing Hook Behavior

```ts
it('updates state and URL together', () => {
  const { result } = renderHook(() => useQueryState('key', parseAsInteger), {
    wrapper: NuqsTestingAdapter
  })

  act(() => {
    result.current[1](42)
  })

  expect(result.current[0]).toBe(42)
  // Verify URL updated via NuqsTestingAdapter
})
```

## Test Organization Best Practices

- **One concept per test** — Single assertion focus
- **Clear naming** — Describe the scenario, not just "it works"
- **Isolate concerns** — Unit tests for logic, e2e for integration
- **Use fixtures** — Reusable test data and setup
- **Cleanup** — Unmount components, clear listeners
- **Type safety** — Use TypeScript for test code too

## Debugging Tests

Enable debug logs:

```ts
// In test file
beforeEach(() => {
  localStorage.setItem('debug', 'nuqs')
})

afterEach(() => {
  localStorage.removeItem('debug')
})
```

Debug output:

- `[nuqs]` — Single-key operations
- `[nuq+]` — Multi-key operations

## CI/CD Integration

- Tests run automatically on pull requests
- Full suite must pass before merge
- Type checking is part of test suite
- No manual intervention needed for test validation


================================================
FILE: .github/FUNDING.yml
================================================
github: [franky47]
liberapay: francoisbest
custom: ['https://paypal.me/francoisbest?locale.x=fr_FR']


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---

<!--
Please read and follow the issue template.
Issues submitted without a reproduction and context
will take longer to resolve.
-->

## Context

What's your version of `nuqs`?

```
-> Paste result from `cat package.json | grep -e nuqs` here
```

What framework are you using?

<!-- Keep whichever is relevant (✅: used, ❌ not used) -->

- ✅/❌ Next.js (app router)
- ✅/❌ Next.js (pages router)
- ✅/❌ React SPA (no router)
- ✅/❌ Remix
- ✅/❌ React Router
- ✅/❌ Other (please specify)

Which version of your framework are you using?

<!-- Note: Next.js information can obtained by running `next info` -->

```
-> Paste the relevant framework versions from your package.json here
```

## Description

<!-- A clear and concise description of what the bug is, and what you expected to happen instead. -->

## Reproduction

<!-- Please provide a minimal reproduction in a CodeSandbox playground or dedicated repository, along with the steps to take to encounter the issue.

Example: Steps to reproduce the behavior:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

 -->


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
  - name: Feature idea
    url: https://github.com/47ng/nuqs/discussions/new?category=ideas
    about: Please share ideas for new features as discussion
  - name: Question
    url: https://github.com/47ng/nuqs/discussions/new?category=q-a
    about: Please use the discussions to ask the community for help


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  # - package-ecosystem: npm
  #   directory: /
  #   schedule:
  #     interval: weekly
  #     time: "09:00"
  #     timezone: Europe/Paris
  #   assignees:
  #     - franky47
  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: monthly
    assignees:
      - franky47


================================================
FILE: .github/workflows/analyse-nextjs-release.yml
================================================
name: "Analyse Next.js release"
run-name: "Analyse Next.js ${{ inputs.version }}"

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Next.js version to test against"
        required: true
        type: string

env:
  FORCE_COLOR: 3 # Diplay chalk colors
  VERSION: ${{ inputs.version }}

jobs:
  analyse-release:
    runs-on: ubuntu-24.04-arm
    name: Check for relevant Next.js core changes
    steps:
      - name: Ensure input follows SemVer
        # Source: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
        run: |
          node -e "
            const version = process.env.VERSION;
            const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
            if (!semverRegex.test(version)) {
              console.error(\`Error: Version '\${version}' does not follow SemVer format\`);
              process.exit(1);
            }
            console.log(\`Version '\${version}' is valid SemVer\`);
          "
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install
      - name: Check for changes in app router
        run: ./next-release-analyser.ts --version "${{ env.VERSION }}"
        working-directory: packages/scripts
        env:
          MAILPACE_API_TOKEN: ${{ secrets.MAILPACE_API_TOKEN }}
          EMAIL_ADDRESS_TO: ${{ secrets.EMAIL_ADDRESS_TO }}
          EMAIL_ADDRESS_FROM: ${{ secrets.EMAIL_ADDRESS_FROM }}


================================================
FILE: .github/workflows/ci-cd.yml
================================================
name: CI/CD

on:
  push:
    branches:
      - master
      - beta
      - next
  pull_request:
    types: [opened, reopened, synchronize]
  workflow_dispatch:

env:
  FORCE_COLOR: 3 # Diplay chalk colors

jobs:
  lint:
    name: Linting
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --ignore-scripts --frozen-lockfile --workspace-root
      - name: Check monorepo with Sherif
        run: pnpm run lint:sherif
      - name: Check source code formatting
        run: |
          set +e # Allow Prettier to fail, but capture the error code
          output=$(./node_modules/.bin/prettier --list-different ./packages/nuqs 2>&1)
          exit_code=$?
          set -e
          if [ $exit_code -ne 0 ]; then
            echo "$output" | while IFS= read -r file; do
              echo "::warning file=$file::Prettier detected formatting issues in $file"
            done
            exit $exit_code
          else
            echo "No formatting issues found"
          fi

  publint:
    name: Package Linting
    runs-on: ubuntu-24.04-arm
    needs: [ci-core]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --ignore-scripts --frozen-lockfile --filter nuqs...
      - name: Build package
        run: pnpm build --filter nuqs
      - name: Run publint on package.json
        run: pnpm publint packages/nuqs
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: publint
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  ci-scripts:
    name: CI (scripts)
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --ignore-scripts --frozen-lockfile --filter scripts
      - name: Run tests
        run: pnpm run test --filter scripts

  ci-core:
    name: CI (core)
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --ignore-scripts --frozen-lockfile --filter nuqs...
      - name: Install Playwright Chromium
        run: ./node_modules/.bin/playwright install chromium
        working-directory: packages/nuqs
      - name: Run tests
        run: pnpm run test ${{ github.event_name == 'workflow_dispatch' && '--force' || '' }} --filter nuqs
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}

  docs:
    name: Docs Typecheck & Build
    runs-on: ubuntu-24.04-arm
    needs: [ci-core]
    permissions:
      contents: read
      actions: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --filter docs...
      - name: Type-check docs
        run: pnpm run test --filter docs
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
      - name: Build docs
        run: pnpm run build --filter docs
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: docs
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  e2e-next:
    # Watch out! When changing the job name,
    # update the required checks in GitHub
    # branch protection settings for `next`.
    name: E2E (next@${{ matrix.next-version }}${{ matrix.base-path && ' ⚾' || ''}}${{ matrix.react-compiler && ' ⚛️' || ''}}${{ matrix.cache-components && ' 💾' || ''}})
    runs-on: ubuntu-24.04-arm
    needs: [ci-core]
    strategy:
      fail-fast: false
      matrix:
        # Watch out! When changing the compat grid,
        # update the required checks in GitHub
        # branch protection settings for `next`.
        base-path: [false]
        react-compiler: [false]
        cache-components: [false]
        next-version:
          # Only keep versions where there were relevant changes in the app router core,
          # and the previous one to use as a baseline.
          - "14.2.0"
          # - '14.2.3' # before vercel/next.js#66755
          - "14.2.4" # after vercel/next.js#66755
          # - '14.2.7' # before vercel/next.js#69509
          - "14.2.8" # after vercel/next.js#69509
          - "15.0.0"
          - "15.1.0"
          - "15.2.0"
          - latest
        include:
          - next-version: "14.2.0"
            base-path: "/base"
          - next-version: "15.0.0"
            base-path: "/base"
          - next-version: "latest"
            base-path: "/base"
          - next-version: "latest"
            react-compiler: true
          - next-version: "latest"
            base-path: "/base"
            react-compiler: true
          - next-version: "latest"
            cache-components: true
            react-compiler: true
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile ${{ matrix.next-version != 'latest' && '--filter e2e-next...' || '' }}
      - name: Install Next.js version ${{ matrix.next-version }}
        if: ${{ matrix.next-version != 'local' }}
        run: pnpm add --filter e2e-next next@${{ matrix.next-version }}
      - name: Run cacheComponents codemod
        if: ${{ matrix.cache-components }}
        run: pnpm run cacheComponents:codemod
        working-directory: packages/e2e/next
      - name: Run integration tests
        run: pnpm run test ${{ github.event_name == 'workflow_dispatch' && '--force' || '' }} --filter e2e-next
        env:
          BASE_PATH: ${{ matrix.base-path && matrix.base-path || '/' }}
          REACT_COMPILER: ${{ matrix.react-compiler }}
          CACHE_COMPONENTS: ${{ matrix.cache-components }}
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}
      - name: Save Playwright report
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        if: failure()
        with:
          path: packages/e2e/next/.playwright/*
          name: playwright-next-${{ matrix.next-version }}${{ matrix.base-path && '-basePath' || ''}}${{ matrix.react-compiler && '-react-compiler' || ''}}${{ matrix.cache-components && '-cache-components' || ''}}
          include-hidden-files: true
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: next@${{ matrix.next-version }}${{ matrix.base-path && ' basePath' || ''}}${{ matrix.react-compiler && ' react-compiler' || ''}}${{ matrix.cache-components && '-cache-components' || ''}}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  e2e-react:
    name: E2E (react-fpn-${{ matrix.full-page-nav-on-shallow-false }})
    runs-on: ubuntu-24.04-arm
    needs: [ci-core]
    strategy:
      fail-fast: false
      matrix:
        full-page-nav-on-shallow-false: [false, true]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --filter e2e-react...
      - name: Run tests
        run: pnpm run test ${{ github.event_name == 'workflow_dispatch' && '--force' || '' }} --filter e2e-react
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}
          FULL_PAGE_NAV_ON_SHALLOW_FALSE: ${{ matrix.full-page-nav-on-shallow-false }}
      - name: Save Playwright report
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        if: failure()
        with:
          path: packages/e2e/react/.playwright/*
          name: playwright-react-fpn-${{ matrix.full-page-nav-on-shallow-false }}
          include-hidden-files: true
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: react-fpn-${{ matrix.full-page-nav-on-shallow-false }}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  e2e-react-router:
    name: E2E (react-router ${{ matrix.react-router-version }})
    runs-on: ubuntu-24.04-arm
    needs: [ci-core]
    strategy:
      fail-fast: false
      matrix:
        react-router-version:
          - "v6"
          - "v7"
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --filter e2e-react-router-${{ matrix.react-router-version }}...
      - name: Run tests
        run: pnpm run test ${{ github.event_name == 'workflow_dispatch' && '--force' || '' }} --filter e2e-react-router-${{ matrix.react-router-version }}
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}
      - name: Save Playwright report
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        if: failure()
        with:
          path: packages/e2e/react-router/${{ matrix.react-router-version }}/.playwright/*
          name: playwright-react-router-${{ matrix.react-router-version }}
          include-hidden-files: true
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: react-router-${{ matrix.react-router-version }}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  e2e-remix:
    name: E2E (remix)
    runs-on: ubuntu-24.04-arm
    needs: [ci-core]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --filter e2e-remix...
      - name: Run tests
        run: pnpm run test ${{ github.event_name == 'workflow_dispatch' && '--force' || '' }} --filter e2e-remix
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}
      - name: Save Playwright report
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        if: failure()
        with:
          path: packages/e2e/remix/.playwright/*
          name: playwright-remix
          include-hidden-files: true
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: remix
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  e2e-tanstack-router:
    name: E2E (tanstack-router)
    runs-on: ubuntu-22.04-arm
    needs: [ci-core]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --filter e2e-tanstack-router...
      - name: Run tests
        run: pnpm run test ${{ github.event_name == 'workflow_dispatch' && '--force' || '' }} --filter e2e-tanstack-router
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}
      - name: Save Playwright report
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        if: failure()
        with:
          path: packages/e2e/tanstack-router/.playwright/*
          name: playwright-tanstack-router
          include-hidden-files: true
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: tanstack-router
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  ci-notify:
    name: Notify on Slack
    runs-on: ubuntu-24.04-arm
    needs:
      - docs
      - lint
      - publint
      - ci-scripts
      - ci-core
      - e2e-next
      - e2e-react
      - e2e-react-router
      - e2e-remix
      - e2e-tanstack-router
    steps:
      - uses: 47ng/actions-slack-notify@main
        with:
          status: ${{ job.status }}
          jobName: Continuous Integration
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  cd:
    name: Deployment
    runs-on: ubuntu-24.04-arm
    permissions:
      contents: write # to be able to publish a GitHub release
      issues: write # to be able to comment on released issues
      pull-requests: write # to be able to comment on released pull requests
      id-token: write # to enable use of OIDC for NPM provenance / trusted publishing
    needs:
      - docs
      - lint
      - publint
      - ci-scripts
      - ci-core
      - e2e-next
      - e2e-react
      - e2e-react-router
      - e2e-remix
      - e2e-tanstack-router
    if: ${{ github.ref_name == 'master' || github.ref_name == 'beta' }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          # No pnpm cache restore in CD: a poisoned cache could inject
          # compromised packages into the published build. Fresh install
          # from the registry ensures integrity (same rationale as
          # skipping external Turbo cache below).
      - name: Update npm # Ensure npm 11.5.1 or later is installed for OIDC trusted publishing
        run: npm install -g npm@latest
      - name: Install dependencies
        run: pnpm install --ignore-scripts --frozen-lockfile --filter nuqs...
      - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies
        run: npm audit signatures
      - name: Build package
        run: pnpm build --filter nuqs
      - name: Semantic Release
        run: ../../node_modules/.bin/semantic-release
        working-directory: packages/nuqs
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Read package version
        id: package-version
        run: |
          VERSION=$(jq -r '.version' package.json)
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Released version: $VERSION"
        working-directory: packages/nuqs
      - name: Invalidate contributors ISR cache in the docs
        if: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
        run: |
          curl -s "https://nuqs.dev/api/isr?tag=contributors&token=${{ secrets.ISR_TOKEN }}"
      - name: Install dependencies
        if: ${{ github.event_name == 'push' && steps.package-version.outputs.version != '0.0.0-semantically-released' }}
        run: pnpm install --ignore-scripts --frozen-lockfile --filter scripts
      - name: Generate release notes
        id: release-notes
        if: ${{ github.event_name == 'push' && steps.package-version.outputs.version != '0.0.0-semantically-released' }}
        run: |
          NOTES=$(./release-notes-automation.ts)
          echo "$NOTES" >> $GITHUB_STEP_SUMMARY
          {
            echo 'notes<<EOF'
            echo "$NOTES"
            echo 'EOF'
          } >> $GITHUB_OUTPUT
        working-directory: packages/scripts
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Update GitHub release notes
        if: ${{ github.event_name == 'push' && steps.package-version.outputs.version != '0.0.0-semantically-released' }}
        run: |
          echo "${{ steps.release-notes.outputs.notes }}" | \
           gh release edit "v${{ steps.package-version.outputs.version }}" \
            --notes-file -
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/clear-shipping-next.yml
================================================
name: Clear "Shipping Next"

on:
  workflow_dispatch:

env:
  SHIPPING_NEXT_MILESTONE_ID: 2 # ID for "Shipping Next" milestone

permissions:
  pull-requests: write
  issues: write

jobs:
  clear_shipping_next:
    name: Clear "Shipping Next" Milestone
    runs-on: ubuntu-24.04-arm

    steps:
      - name: Get issues & PRs in "Shipping Next" milestone
        id: get_issues
        run: |
          # Fetch issues with titles
          response=$(gh api -X GET \
            repos/${{ github.repository }}/issues \
            -f milestone=${{ env.SHIPPING_NEXT_MILESTONE_ID }} \
            -f state=all \
            -f labels=released)

          # Extract just the numbers for the output
          issues=$(echo "$response" | jq -r '[.[].number] | join(" ")')
          echo "issues=$issues" >> $GITHUB_OUTPUT

          # Add step summary with titles
          if [ -n "$issues" ]; then
            echo "## Issues & PRs to clear from 'Shipping Next' milestone" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            echo "$response" | jq -r '.[] | "- [#\(.number)](https://github.com/${{ github.repository }}/issues/\(.number)) \(.title)"' >> $GITHUB_STEP_SUMMARY
          else
            echo "No issues or PRs found in the 'Shipping Next' milestone with the 'released' label." >> $GITHUB_STEP_SUMMARY
          fi
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Clear milestone from issues & PRs
        if: steps.get_issues.outputs.issues != ''
        run: |
          for issue_number in ${{ steps.get_issues.outputs.issues }}; do
            gh api -X PATCH \
              repos/${{ github.repository }}/issues/$issue_number \
              -F milestone=null
          done
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/milestone-automation.yml
================================================
name: Mark as "Shipping Next"

on:
  pull_request_target:
    types: [closed]
    branches:
      - next

env:
  BACKLOG_MILESTONE_ID: 3 # ID for "Backlog" milestone
  SHIPPING_NEXT_MILESTONE_ID: 2 # ID for "Shipping Next" milestone

permissions:
  pull-requests: write
  issues: write

jobs:
  update_milestones:
    name: Update Milestones
    runs-on: ubuntu-24.04-arm
    if: github.event.pull_request.merged == true

    steps:
      - name: Check if PR was in Backlog
        id: check_milestone
        run: |
          milestone_id=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }} --jq '.milestone.number')
          if [[ "$milestone_id" == "${{ env.BACKLOG_MILESTONE_ID }}" ]]; then
            echo "backlog_milestone=true" >> $GITHUB_OUTPUT
          else
            echo "backlog_milestone=false" >> $GITHUB_OUTPUT
          fi
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Update PR milestone to "shipping next"
        if: steps.check_milestone.outputs.backlog_milestone == 'true'
        run: |
          gh api -X PATCH \
            repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }} \
            -f milestone=${{ env.SHIPPING_NEXT_MILESTONE_ID }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Update linked issues milestone to "shipping next"
        if: steps.check_milestone.outputs.backlog_milestone == 'true'
        run: |
          set -euo pipefail # Exit on any error

          # Validate PR number is numeric
          if ! [[ "${{ github.event.pull_request.number }}" =~ ^[0-9]+$ ]]; then
            echo "Invalid PR number: ${{ github.event.pull_request.number }}"
            exit 1
          fi

          # Get linked issues using GraphQL API
          query='query LinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
            repository(owner: $owner, name: $repo) {
              pullRequest(number: $prNumber) {
                closingIssuesReferences(first: 20) {
                  nodes {
                    number
                    milestone {
                      number
                    }
                  }
                }
              }
            }
          }'

          # Extract owner and repo from repository
          owner=$(echo "${{ github.repository }}" | cut -d'/' -f1)
          repo=$(echo "${{ github.repository }}" | cut -d'/' -f2)

          # Execute GraphQL query with error handling
          echo "Fetching linked issues for PR #${{ github.event.pull_request.number }}"

          if ! response=$(gh api graphql \
            -f query="$query" \
            -f owner="$owner" \
            -f repo="$repo" \
            -F prNumber="${{ github.event.pull_request.number }}" 2>&1); then
            echo "Failed to fetch linked issues: $response"
            exit 1
          fi

          # Extract issue numbers, keep only those with milestone "Backlog" (number 3)
          linked_issues=$(echo "$response" | jq -r '
            .data.repository.pullRequest.closingIssuesReferences.nodes[]
            | select(.milestone != null and .milestone.number == ${{ env.BACKLOG_MILESTONE_ID }})
            | .number
          ')

          # Check if there are any issues to update
          if [[ -z "$linked_issues" ]]; then
            echo "No linked issues found or all issues already have the correct milestone"
            exit 0
          fi

          echo "Found linked issues to update: $(echo "$linked_issues" | tr '\n' ' ')"

          # Update milestone for each linked issue
          failed_updates=0
          updated_count=0

          while IFS= read -r issue_number; do
            [[ -z "$issue_number" ]] && continue

            echo "Updating milestone for issue #$issue_number"
            if gh api -X PATCH \
              "repos/${{ github.repository }}/issues/$issue_number" \
              -f milestone=${{ env.SHIPPING_NEXT_MILESTONE_ID }} \
              --silent; then
              echo "✓ Successfully updated milestone for issue #$issue_number"
              updated_count=$((updated_count + 1))
            else
              echo "✗ Failed to update milestone for issue #$issue_number"
              failed_updates=$((failed_updates + 1))
            fi
          done <<< "$linked_issues"

          echo "Summary: Updated $updated_count issue(s), $failed_updates failure(s)"

          # Fail the step if any updates failed
          if [[ $failed_updates -gt 0 ]]; then
            echo "Failed to update $failed_updates issue(s)"
            exit 1
          fi
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/pkg.pr.new.yml
================================================
name: PR Preview
on:
  pull_request:
    types: [opened, synchronize, labeled]
    paths:
      - 'packages/nuqs/**'

concurrency:
  group: pkg-pr-new-${{ github.event.pull_request.number }}
  cancel-in-progress: false

jobs:
  deploy-preview:
    name: Deploy to pkg.pr.new
    if: |
      contains(github.event.pull_request.author_association, 'MEMBER') ||
      contains(github.event.pull_request.labels.*.name, 'deploy:preview')
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install
      - name: Build package
        run: pnpm build --filter nuqs
      - name: Set package version
        run: |
          pnpm pkg set version=0.0.0-preview.${{ github.event.pull_request.head.sha }}
          echo "::notice title=Install (PR)::pnpm add https://pkg.pr.new/nuqs@${{ github.event.pull_request.number }}"
          echo "::notice title=Install (SHA)::pnpm add https://pkg.pr.new/nuqs@${{ github.event.pull_request.head.sha }}"
          echo "::notice title=Version::0.0.0-preview.${{ github.event.pull_request.head.sha }}"
        working-directory: packages/nuqs
      - name: Publish to pkg.pr.new
        run: pnpx pkg-pr-new publish --compact './packages/nuqs' --no-template --packageManager=pnpm --pnpm


================================================
FILE: .github/workflows/pr-base-enforcement.yml
================================================
name: Prevent PRs targetting master

on:
  pull_request:
    types: [opened, edited]
    branches:
      - master

jobs:
  prevent-pr-targetting-master:
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - name: Post comment to update base branch
        run: gh pr comment ${{ github.event.pull_request.number }} --body "⚠️ Pull requests targetting the \`master\` branch are not allowed. Please update the base branch to \`next\` before reopening."
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Close PR
        run: gh pr close ${{ github.event.pull_request.number }} --repo ${{ github.repository }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/pr-lint.yml
================================================
name: Lint PR Title

on:
  pull_request:
    types:
      - opened
      - edited
      - synchronize

jobs:
  lint-pr-title:
    name: Lint PR Title
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
        with:
          fetch-depth: 0
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm add -D @commitlint/load @commitlint/lint @commitlint/parse
      - name: Lint PR title
        env:
          TITLE: ${{ github.event.pull_request.title }}
        run: |
          node -e "
            import loadConfig from '@commitlint/load';
            import lint from '@commitlint/lint';
            import pkgJson from './package.json' with { type: 'json' };
            const config = await loadConfig(pkgJson.commitlint);
            const result = await lint(process.env.TITLE, config.rules, config.parserPreset ? { parserOpts: config.parserPreset.parserOpts } : {});
            process.env.GITHUB_STEP_SUMMARY += \`## Linting Result\n- Valid: \${result.valid}\n\`;
            if (result.valid === false) {
              for (const { message } of result.errors) {
                process.env.GITHUB_STEP_SUMMARY += \`- Error: \${message}\n\`;
                console.error(message);
              }
              process.exit(1);
            }
          "
      - name: Get changed files
        id: changed-files
        run: echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
      - name: Check version-bumping commits target core package
        env:
          TITLE: ${{ github.event.pull_request.title }}
          CHANGED_FILES: ${{ steps.changed-files.outputs.files }}
        run: |
          node -e "
            import parse from '@commitlint/parse';
            import { appendFile } from 'node:fs/promises';

            // Commit types that trigger version bumps (semantic-release defaults)
            const VERSION_BUMPING_TYPES = ['feat', 'fix', 'perf', 'revert'];
            // Non-bumping types for reference in error messages
            const NON_BUMPING_TYPES = ['build', 'chore', 'ci', 'clean', 'doc', 'ref', 'style', 'test'];

            const parsed = await parse(process.env.TITLE);
            const commitType = parsed.type;

            if (!VERSION_BUMPING_TYPES.includes(commitType)) {
              console.log(\`Commit type '\${commitType}' does not trigger a version bump. Skipping core package check.\`);
              process.exit(0);
            }

            console.log(\`Commit type '\${commitType}' triggers a version bump. Checking for changes in packages/nuqs...\`);

            const changedFiles = process.env.CHANGED_FILES.trim().split(' ').filter(Boolean);
            const hasCoreChanges = changedFiles.some(file => file.startsWith('packages/nuqs/'));

            if (!hasCoreChanges) {
              const summary = \`## ❌ Version Bump Check Failed

            Your PR title uses the commit type **\\\`\${commitType}\\\`** which triggers a version bump, but no changes were found in the core package (\\\`packages/nuqs\\\`).

            ### What to do:

            If this PR does not include changes to the core \\\`nuqs\\\` package, please use a non-bumping commit type instead:

            | Type | Use for |
            |------|---------|
            | \\\`doc\\\` | Documentation updates |
            | \\\`chore\\\` | Maintenance, CI/CD, dependencies |
            | \\\`test\\\` | Test additions or modifications |
            | \\\`ci\\\` | CI configuration changes |
            | \\\`build\\\` | Build system changes |
            | \\\`style\\\` | Code style/formatting |
            | \\\`ref\\\` | Refactoring (non-core) |

            ### Version-bumping types (require core package changes):
            - \\\`feat\\\` → minor version bump
            - \\\`fix\\\` → patch version bump
            - \\\`perf\\\` → patch version bump
            - \\\`revert\\\` → depends on reverted commit
            \`;

              await appendFile(process.env.GITHUB_STEP_SUMMARY, summary);
              console.error(\`Error: PR title uses version-bumping type '\${commitType}' but contains no changes in packages/nuqs\`);
              console.error(\`Changed files: \${changedFiles.join(', ')}\`);
              console.error(\`\nPlease use a non-bumping commit type: \${NON_BUMPING_TYPES.join(', ')}\`);
              process.exit(1);
            }

            console.log('✓ Version-bumping commit type is valid: core package has changes.');
            await appendFile(process.env.GITHUB_STEP_SUMMARY, \`## ✅ Version Bump Check Passed\n\nCommit type \\\`\${commitType}\\\` is valid because the PR includes changes to \\\`packages/nuqs\\\`.\n\`);
          "


================================================
FILE: .github/workflows/test-against-nextjs-release.yml
================================================
name: "Test against Next.js release"
run-name: "Test against Next.js ${{ inputs.version }}"

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Next.js version to test against"
        required: true
        type: string

env:
  FORCE_COLOR: 3 # Diplay chalk colors
  VERSION: ${{ inputs.version }}

jobs:
  test_against_nextjs_release:
    name: CI (next@${{ inputs.version }}${{ (matrix.base-path || matrix.cache-components || matrix.react-compiler) && ' ' || ''}}${{ matrix.base-path && '⚾' || ''}}${{ matrix.react-compiler && '⚛️' || ''}}${{ matrix.cache-components && '💾' || ''}})
    runs-on: ubuntu-24.04-arm
    strategy:
      fail-fast: false
      matrix:
        base-path: [false, "/base"]
        react-compiler: [true, false]
        cache-components: ${{ startsWith(inputs.version, '16.') && fromJson('[true, false]') || fromJson('[false]') }}
    steps:
      - name: Ensure input follows SemVer
        # Source: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
        run: |
          node -e "
            const version = process.env.VERSION;
            const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
            if (!semverRegex.test(version)) {
              console.error(\`Error: Version '\${version}' does not follow SemVer format\`);
              process.exit(1);
            }
            console.log(\`Version '\${version}' is valid SemVer\`);
          "
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install
      - name: Install Next.js version ${{ env.VERSION }}
        run: pnpm add --filter e2e-next --filter nuqs "next@${{ env.VERSION }}"
      - name: Run cacheComponents codemod
        if: ${{ matrix.cache-components }}
        run: pnpm run cacheComponents:codemod
        working-directory: packages/e2e/next
      - name: Run integration tests
        run: pnpm run test --filter e2e-next
        env:
          BASE_PATH: ${{ matrix.base-path && matrix.base-path || '/' }}
          REACT_COMPILER: ${{ matrix.react-compiler }}
          CACHE_COMPONENTS: ${{ matrix.cache-components }}
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          E2E_NO_CACHE_ON_RERUN: ${{ github.run_attempt }}
      - name: Save Playwright report
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        if: failure()
        with:
          path: packages/e2e/next/.playwright/*
          name: playwright-next-${{ env.VERSION }}${{ matrix.base-path && '-basePath' || ''}}${{ matrix.react-compiler && '-react-compiler' || ''}}${{ matrix.cache-components && '-cache-components' || ''}}
          include-hidden-files: true
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: next@${{ env.VERSION }}${{ matrix.base-path && ' basePath' || ''}}${{ matrix.react-compiler && ' react-compiler' || ''}}${{ matrix.cache-components && '-cache-components' || ''}}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  docs:
    name: Docs (next@${{ inputs.version }})
    if: ${{ startsWith(inputs.version, '16.') }}
    runs-on: ubuntu-24.04-arm
    permissions:
      contents: read
      actions: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238
        with:
          node-version-file: .node-version
          cache: pnpm
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --filter docs...
      - name: Install Next.js version ${{ env.VERSION }}
        run: pnpm add --filter docs --filter nuqs "next@${{ env.VERSION }}"
      - name: Type-check docs
        run: pnpm run test --filter docs
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
      - name: Build docs
        run: pnpm run build --filter docs
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - uses: 47ng/actions-slack-notify@main
        name: Notify on Slack
        if: failure()
        with:
          status: ${{ job.status }}
          jobName: docs (next@${{ env.VERSION }})
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  invalidate-isr-cache:
    name: Invalidate ISR cache
    runs-on: ubuntu-24.04-arm
    needs:
      - test_against_nextjs_release
      - docs
    if: ${{ always() }}
    steps:
      - name: Invalidate ISR cache for GitHub Actions status on landing page
        run: curl -s "https://nuqs.dev/api/isr?tag=github-actions-status&token=${{ secrets.ISR_TOKEN }}"

  notify:
    name: Notify on Slack
    runs-on: ubuntu-24.04-arm
    needs:
      - test_against_nextjs_release
      - docs
    if: ${{ needs.test_against_nextjs_release.result == 'success' && (needs.docs.result == 'success' || needs.docs.result == 'skipped') }}
    steps:
      - uses: 47ng/actions-slack-notify@main
        with:
          status: ${{ job.status }}
          jobName: "${{ env.VERSION }}"
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}


================================================
FILE: .gitignore
================================================
node_modules/
dist/
coverage/
.env
yarn-error.log
# Docker containers with persistance
.volumes/
package-lock.json
.next/
.turbo/
.vercel
*.tsbuildinfo


================================================
FILE: .husky/commit-msg
================================================
pnpm commitlint --edit $1


================================================
FILE: .node-version
================================================
24.11.0


================================================
FILE: .vscode/settings.json
================================================
{
  "editor.tabSize": 2,
  "editor.insertSpaces": true,
  "githubPullRequests.ignoredPullRequestBranches": ["next", "master"],
  "githubPullRequests.queries": [
    {
      "label": "Backlog",
      "query": "repo:47ng/nuqs is:pr is:open milestone:\"🪵 Backlog\""
    },
    {
      "label": "Docs",
      "query": "repo:47ng/nuqs is:pr is:open label:documentation draft:false"
    },
    {
      "label": "All reviewable",
      "query": "repo:47ng/nuqs is:pr is:open draft:false",
      "groupBy": ["milestone"]
    }
  ],
  "githubIssues.queries": [
    {
      "label": "Backlog",
      "query": "repo:47ng/nuqs is:issue is:open milestone:\"🪵 Backlog\""
    },
    {
      "label": "Bugs",
      "query": "repo:47ng/nuqs is:issue is:open label:bug"
    },
    {
      "label": "Open Issues",
      "query": "repo:47ng/nuqs is:issue is:open -label:internal",
      "groupBy": ["milestone"]
    },
    {
      "label": "Internal",
      "query": "repo:47ng/nuqs is:issue label:internal"
    }
  ],
  "typescript.preferences.autoImportSpecifierExcludeRegexes": [
    "^node:test$" // We use Vitest
  ]
}


================================================
FILE: AGENTS.md
================================================
# AGENTS GUIDE

Operational instructions for autonomous coding / AI agents contributing to the nuqs repository.

**nuqs** is a library for type-safe URL query string ↔ React state synchronization with minimal bundle size and zero dependencies.

Refer to: [README.md](README.md) & [CONTRIBUTING.md](CONTRIBUTING.md) for authoritative detail.

---

## Essential Context

### Repository Structure (Monorepo)

- **Library source:** `packages/nuqs`
- **Documentation app** (Next.js + Fumadocs): `packages/docs`
  - MDX content: `packages/docs/content`
- **End-to-end test benches:** `packages/e2e`
  - Framework targets: Next.js app/pages, React SPA, Remix, TanStack Router, React Router v6/v7
- **Examples:** `packages/examples/*`

### Core Concepts (nuqs)

- **Goal:** Type-safe URL query string ↔ React state sync.
- **Main Hooks:**
  - `useQueryState(key, parserOrConfig)`
  - `useQueryStates(configObject, options)`
- **Parsers:** Provide `parse` & `serialize`; enhanced with `.withDefault()` & `.withOptions()`
- **Batching & Throttling:** Multiple state updates in one tick are merged; URL updates throttled (≥50ms)
- **Key Principles:**
  1. URL = single source of truth
  2. Serialization must be lossless & pure
  3. Defaults are internal (not written to URL)
  4. Invalid parse → return `null`

### Configuration

- **Package manager:** `pnpm`
- **Build:** `pnpm build`
- **Test suite:** `pnpm test` (5-10 minutes; includes build + unit + typing + e2e)
- **Development:** `pnpm dev --filter <package-name>...` (triple dots start dependencies' dev script too)

---

## Development Guidelines

For detailed development guidelines organized by task, see:

- **[Adapter Development](.agents/docs/adapter-development.md)** — Adding framework adapters
- **[Parser Implementation](.agents/docs/parser-implementation.md)** — Creating custom parsers
- **[API Design & Architecture](.agents/docs/api-design.md)** — Design principles, extensibility, type safety
- **[Testing Patterns](.agents/docs/testing.md)** — Unit, type-level, and e2e testing strategies
- **[Release & Git Workflow](.agents/docs/git-workflow.md)** — Conventional commits, semantic versioning, PR standards
- **[Quality Standards](.agents/docs/quality-standards.md)** — Checklists, performance, security, anti-patterns

---

## Quick Reference: Common Tasks

| Task                    | Guide                                                                             |
| ----------------------- | --------------------------------------------------------------------------------- |
| Fix a bug               | See [Testing Patterns](.agents/docs/testing.md) → Regression                      |
| Add a new parser        | See [Parser Implementation](.agents/docs/parser-implementation.md)                |
| Add a framework adapter | See [Adapter Development](.agents/docs/adapter-development.md)                    |
| Improve performance     | See [API Design](.agents/docs/api-design.md) → Performance & Reliability          |
| Update documentation    | See [Release & Git Workflow](.agents/docs/git-workflow.md) → Documentation        |
| Prepare a pull request  | See [Release & Git Workflow](.agents/docs/git-workflow.md) → PR Quality Checklist |

---

## Debugging

Enable debug logs in the browser console:

```js
localStorage.setItem('debug', 'nuqs')
```

In server or Node environments (e.g. when using `nuqs/server`), set the `DEBUG` environment variable so it contains `nuqs`:

```bash
DEBUG=nuqs pnpm dev
```

Log lines are prefixed with `[nuq+]`

Encourage debug logs in issue reports and include them in reproduction scripts.

---

## Exit Conditions for Agent Tasks

A task is **DONE** when:

- All checklist items satisfied
- Tests pass locally (`pnpm test`)
- Docs consistent with behavior
- No unresolved TODOs introduced
- No stray console logs (except controlled debug support)


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
code-of-conduct@47ng.com.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: CONTRIBUTING.md
================================================
# Contribution Guidelines

First off, thanks for your help! 🙏

## Getting started

1. Fork and clone the repository
2. Install dependencies with `pnpm install`
3. Start the development environment with `pnpm dev`

## Project structure

This monorepo contains:

- The source code for the `nuqs` NPM package, in [`packages/nuqs`](./packages/nuqs).
- A Next.js app under [`packages/docs`](./packages/docs) that serves the documentation and as a playground deployed at <https://nuqs.dev>
- Test benches for [end-to-end tests](./packages/e2e) for each supported framework, driven by Playwright
- Examples of integration with other tools.

When running `next dev`, this will:

- Build the library and watch for changes using [`tsup`](https://tsup.egoist.dev/)
- Start the docs app, which will be available at <http://localhost:3000>.
- Start the end-to-end test benches:
  - http://localhost:3001 - [Next.js](./packages/e2e/next)
  - http://localhost:3002 - [React SPA](./packages/e2e/react)
  - http://localhost:3003 - [Remix](./packages/e2e/remix)
  - http://localhost:3004 - [TanStack Router](./packages/e2e/tanstack-router)
  - http://localhost:3005 - [React Router v5](./packages/e2e/react-router/v5)
  - http://localhost:3006 - [React Router v6](./packages/e2e/react-router/v6)
  - http://localhost:3007 - [React Router v7](./packages/e2e/react-router/v7)
- Start the examples:
  - http://localhost:4000 - [tRPC](./packages/examples/trpc)
  - http://localhost:4001 - [Next.js - App router](./packages/examples/next-app)

## Testing

You can run the complete integration test suite with `pnpm test` from the root of the repository.

It will build the library, run unit tests and typing tests against it, and then
run the end-to-end tests against the test bench apps (which uses the built library).

When proposing changes or fixing a bug, adding tests (unit or in the
appropriate e2e test environment) can help tremendously to validate and
understand the changes.

## Opening issues

Please follow the [issue template](.github/ISSUE_TEMPLATE/bug_report.md) when opening a new issue.

A minimal reproduction example is very helpful to understand the issue and
inspect it locally.

## Proposing changes

Make sure your changes:

1. Pass the tests: `pnpm test`
2. Pass linting checks: `pnpm lint`
3. Have relevant documentation additions / updates (in the `packages/docs/content` and the README.md file).

This repository uses [`semantic-release`](https://semantic-release.gitbook.io/semantic-release/)
to automatically publish new versions of the package to NPM.
To do this, the Git history follows the
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format.

Pull requests should target the `next` branch.

If your changes impact the `nuqs` package, you'll get a comment from [pkg.pr.new](https://pkg.pr.new)
with a preview deployment of the package you can install in your application.

If you are proposing a bug fix, pushing a failing test first (with a note in the
PR description) is very helpful in showcasing the issue and validating the fix in
a follow-up commit (test-driven development).


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 François Best <contact@francoisbest.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# nuqs

[![NPM](https://img.shields.io/npm/v/nuqs?color=red)](https://www.npmjs.com/package/nuqs)
[![MIT License](https://img.shields.io/github/license/47ng/nuqs.svg?color=blue)](https://github.com/47ng/nuqs/blob/next/LICENSE)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/franky47?color=%23db61a2&label=Sponsors)](https://github.com/sponsors/franky47)
[![CI/CD](https://github.com/47ng/nuqs/actions/workflows/ci-cd.yml/badge.svg?branch=next)](https://github.com/47ng/nuqs/actions/workflows/ci-cd.yml)
[![Depfu](https://badges.depfu.com/badges/acad53fa2b09b1e435a19d6d18f29af4/count.svg)](https://depfu.com/github/47ng/nuqs?project_id=22104)

Type-safe search params state manager for React frameworks. Like `useState`, but stored in the URL query string.

## Features

- 🔀 **new:** Supports Next.js (`app` and `pages` routers), plain React (SPA), Remix, React Router, TanStack Router, and custom routers via [adapters](#adapters)
- 🧘‍♀️ Simple: the URL is the source of truth
- 🕰 Replace history or [append](#history) to use the Back button to navigate state updates
- ⚡️ Built-in [parsers](#parsing) for common state types (integer, float, boolean, Date, and more). Create your own parsers for custom types & pretty URLs
- ♊️ Related querystrings with [`useQueryStates`](#usequerystates)
- 📡 [Shallow mode](#shallow) by default for URL query updates, opt-in to notify server components
- 🗃 [Server cache](#accessing-searchparams-in-server-components) for type-safe searchParams access in nested server components
- ⌛️ Support for [`useTransition`](#transitions) to get loading states on server updates

## Documentation

Read the complete documentation at [nuqs.dev](https://nuqs.dev).

## Installation

```shell
pnpm add nuqs
```

```shell
yarn add nuqs
```

```shell
npm install nuqs
```

## Adapters

You will need to wrap your React component tree with an adapter for your framework. _(expand the appropriate section below)_

<details><summary>▲ Next.js (app router)</summary>

> Supported Next.js versions: `>=14.2.0`. For older versions, install `nuqs@^1` (which doesn't need this adapter code).

```tsx
// src/app/layout.tsx
import { NuqsAdapter } from 'nuqs/adapters/next/app'
import { type ReactNode } from 'react'

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html>
      <body>
        <NuqsAdapter>{children}</NuqsAdapter>
      </body>
    </html>
  )
}
```

</details>

<details><summary>▲ Next.js (pages router)</summary>

> Supported Next.js versions: `>=14.2.0`. For older versions, install `nuqs@^1` (which doesn't need this adapter code).

```tsx
// src/pages/_app.tsx
import type { AppProps } from 'next/app'
import { NuqsAdapter } from 'nuqs/adapters/next/pages'

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <NuqsAdapter>
      <Component {...pageProps} />
    </NuqsAdapter>
  )
}
```

</details>

<details><summary>⚛️ Plain React (SPA)</summary>

Example: via Vite or create-react-app.

```tsx
import { NuqsAdapter } from 'nuqs/adapters/react'

createRoot(document.getElementById('root')!).render(
  <NuqsAdapter>
    <App />
  </NuqsAdapter>
)
```

</details>

<details><summary>💿 Remix</summary>

> Supported Remix versions: `@remix-run/react@>=2`

```tsx
// app/root.tsx
import { NuqsAdapter } from 'nuqs/adapters/remix'

// ...

export default function App() {
  return (
    <NuqsAdapter>
      <Outlet />
    </NuqsAdapter>
  )
}
```

</details>

<details><summary><span style="width:16px;height:16px;background:#fff;border-radius:2px;"><img width="16px" height="16px" src="https://reactrouter.com/_brand/React%20Router%20Brand%20Assets/React%20Router%20Logo/Light.svg" /></span> React Router v6
</summary>

> Supported React Router versions: `react-router-dom@^6`

```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: <App />
  }
])

export function ReactRouter() {
  return (
    <NuqsAdapter>
      <RouterProvider router={router} />
    </NuqsAdapter>
  )
}
```

</details>

<details><summary><span style="width:16px;height:16px;background:#fff;border-radius:2px;"><img width="16px" height="16px" src="https://reactrouter.com/_brand/React%20Router%20Brand%20Assets/React%20Router%20Logo/Light.svg" /></span> React Router v7
</summary>

> Supported React Router versions: `react-router@^7`

```tsx
// app/root.tsx
import { NuqsAdapter } from 'nuqs/adapters/react-router/v7'
import { Outlet } from 'react-router'

// ...

export default function App() {
  return (
    <NuqsAdapter>
      <Outlet />
    </NuqsAdapter>
  )
}
```

</details>

<details><summary>🏝️ TanStack Router</summary>

> Supported TanStack Router versions: `@tanstack/react-router@^1`
> Note: TanStack Router support is experimental and does not yet cover TanStack Start.

```tsx
// src/routes/__root.tsx
import { NuqsAdapter } from 'nuqs/adapters/tanstack-router'
import { Outlet, createRootRoute } from '@tanstack/react-router'

export const Route = createRootRoute({
  component: () => (
    <>
      <NuqsAdapter>
        <Outlet />
      </NuqsAdapter>
    </>
  )
})
```

</details>

## Usage

```tsx
'use client' // Only works in client components

import { useQueryState } from 'nuqs'

export default () => {
  const [name, setName] = useQueryState('name')
  return (
    <>
      <h1>Hello, {name || 'anonymous visitor'}!</h1>
      <input value={name || ''} onChange={e => setName(e.target.value)} />
      <button onClick={() => setName(null)}>Clear</button>
    </>
  )
}
```

![](https://raw.githubusercontent.com/47ng/nuqs/next/useQueryState.gif)

`useQueryState` takes one required argument: the key to use in the query string.

Like `React.useState`, it returns an array with the value present in the query
string as a string (or `null` if none was found), and a state updater function.

Example outputs for our hello world example:

| URL          | name value | Notes                                                             |
| ------------ | ---------- | ----------------------------------------------------------------- |
| `/`          | `null`     | No `name` key in URL                                              |
| `/?name=`    | `''`       | Empty string                                                      |
| `/?name=foo` | `'foo'`    |
| `/?name=2`   | `'2'`      | Always returns a string by default, see [Parsing](#parsing) below |

## Parsing

If your state type is not a string, you must pass a parsing function in the
second argument object.

We provide parsers for common and more advanced object types:

```ts
import {
  parseAsString,
  parseAsInteger,
  parseAsFloat,
  parseAsBoolean,
  parseAsTimestamp,
  parseAsIsoDateTime,
  parseAsArrayOf,
  parseAsJson,
  parseAsStringEnum,
  parseAsStringLiteral,
  parseAsNumberLiteral
} from 'nuqs'

useQueryState('tag') // defaults to string
useQueryState('count', parseAsInteger)
useQueryState('brightness', parseAsFloat)
useQueryState('darkMode', parseAsBoolean)
useQueryState('after', parseAsTimestamp) // state is a Date
useQueryState('date', parseAsIsoDateTime) // state is a Date
useQueryState('array', parseAsArrayOf(parseAsInteger)) // state is number[]
useQueryState('json', parseAsJson<Point>()) // state is a Point

// Enums (string-based only)
enum Direction {
  up = 'UP',
  down = 'DOWN',
  left = 'LEFT',
  right = 'RIGHT'
}

const [direction, setDirection] = useQueryState(
  'direction',
  parseAsStringEnum<Direction>(Object.values(Direction)) // pass a list of allowed values
    .withDefault(Direction.up)
)

// Literals (string-based only)
const colors = ['red', 'green', 'blue'] as const

const [color, setColor] = useQueryState(
  'color',
  parseAsStringLiteral(colors) // pass a readonly list of allowed values
    .withDefault('red')
)

// Literals (number-based only)
const diceSides = [1, 2, 3, 4, 5, 6] as const

const [side, setSide] = useQueryState(
  'side',
  parseAsNumberLiteral(diceSides) // pass a readonly list of allowed values
    .withDefault(4)
)
```

You may pass a custom set of `parse` and `serialize` functions:

```tsx
import { useQueryState } from 'nuqs'

export default () => {
  const [hex, setHex] = useQueryState('hex', {
    // TypeScript will automatically infer it's a number
    // based on what `parse` returns.
    parse: (query: string) => parseInt(query, 16),
    serialize: value => value.toString(16)
  })
}
```

## Default value

When the query string is not present in the URL, the default behaviour is to
return `null` as state.

It can make state updating and UI rendering tedious. Take this example of a simple counter stored in the URL:

```tsx
import { useQueryState, parseAsInteger } from 'nuqs'

export default () => {
  const [count, setCount] = useQueryState('count', parseAsInteger)
  return (
    <>
      <pre>count: {count}</pre>
      <button onClick={() => setCount(0)}>Reset</button>
      {/* handling null values in setCount is annoying: */}
      <button onClick={() => setCount(c => c ?? 0 + 1)}>+</button>
      <button onClick={() => setCount(c => c ?? 0 - 1)}>-</button>
      <button onClick={() => setCount(null)}>Clear</button>
    </>
  )
}
```

You can specify a default value to be returned in this case:

```ts
const [count, setCount] = useQueryState('count', parseAsInteger.withDefault(0))

const increment = () => setCount(c => c + 1) // c will never be null
const decrement = () => setCount(c => c - 1) // c will never be null
const clearCount = () => setCount(null) // Remove query from the URL
```

Note: the default value is internal to React, it will **not** be written to the
URL.

Setting the state to `null` will remove the key in the query string and set the
state to the default value.

## Options

### History

By default, state updates are done by replacing the current history entry with
the updated query when state changes.

You can see this as a sort of `git squash`, where all state-changing
operations are merged into a single history value.

You can also opt-in to push a new history item for each state change,
per key, which will let you use the Back button to navigate state
updates:

```ts
// Default: replace current history with new state
useQueryState('foo', { history: 'replace' })

// Append state changes to history:
useQueryState('foo', { history: 'push' })
```

Any other value for the `history` option will fallback to the default.

You can also override the history mode when calling the state updater function:

```ts
const [query, setQuery] = useQueryState('q', { history: 'push' })

// This overrides the hook declaration setting:
setQuery(null, { history: 'replace' })
```

### Shallow

> Note: this feature only applies to Next.js

By default, query state updates are done in a _client-first_ manner: there are
no network calls to the server.

This is equivalent to the `shallow` option of the Next.js pages router set to `true`,
or going through the experimental [`windowHistorySupport`](https://github.com/vercel/next.js/discussions/48110)
flag in the app router.

To opt-in to query updates notifying the server (to re-run `getServerSideProps`
in the pages router and re-render Server Components on the app router),
you can set `shallow` to `false`:

```ts
const [state, setState] = useQueryState('foo', { shallow: false })

// You can also pass the option on calls to setState:
setState('bar', { shallow: false })
```

### Throttling URL updates

Because of browsers rate-limiting the History API, internal updates to the
URL are queued and throttled to a default of 50ms, which seems to satisfy
most browsers even when sending high-frequency query updates, like binding
to a text input or a slider.

Safari's rate limits are much stricter and would require a throttle of around 340ms.
If you end up needing a longer time between updates, you can specify it in the
options:

```ts
useQueryState('foo', {
  // Send updates to the server maximum once every second
  shallow: false,
  throttleMs: 1000
})

// You can also pass the option on calls to setState:
setState('bar', { throttleMs: 1000 })
```

> Note: the state returned by the hook is always updated instantly, to keep UI responsive.
> Only changes to the URL, and server requests when using `shallow: false`, are throttled.

If multiple hooks set different throttle values on the same event loop tick,
the highest value will be used. Also, values lower than 50ms will be ignored,
to avoid rate-limiting issues. [Read more](https://francoisbest.com/posts/2023/storing-react-state-in-the-url-with-nextjs#batching--throttling).

### Transitions

When combined with `shallow: false`, you can use the `useTransition` hook to get
loading states while the server is re-rendering server components with the
updated URL.

Pass in the `startTransition` function from `useTransition` to the options
to enable this behaviour:

```tsx
'use client'

import React from 'react'
import { useQueryState, parseAsString } from 'nuqs'

function ClientComponent({ data }) {
  // 1. Provide your own useTransition hook:
  const [isLoading, startTransition] = React.useTransition()
  const [query, setQuery] = useQueryState(
    'query',
    // 2. Pass the `startTransition` as an option:
    parseAsString.withOptions({
      startTransition,
      shallow: false // opt-in to notify the server (Next.js only)
    })
  )
  // 3. `isLoading` will be true while the server is re-rendering
  // and streaming RSC payloads, when the query is updated via `setQuery`.

  // Indicate loading state
  if (isLoading) return <div>Loading...</div>

  // Normal rendering with data
  return <div>{/*...*/}</div>
}
```

## Configuring parsers, default value & options

You can use a builder pattern to facilitate specifying all of those things:

```ts
useQueryState(
  'counter',
  parseAsInteger.withDefault(0).withOptions({
    history: 'push',
    shallow: false
  })
)
```

You can get this pattern for your custom parsers too, and compose them
with others:

```ts
import { createParser, parseAsHex } from 'nuqs'

// Wrapping your parser/serializer in `createParser`
// gives it access to the builder pattern & server-side
// parsing capabilities:
const hexColorSchema = createParser({
  parse(query) {
    if (query.length !== 6) {
      return null // always return null for invalid inputs
    }
    return {
      // When composing other parsers, they may return null too.
      r: parseAsHex.parse(query.slice(0, 2)) ?? 0x00,
      g: parseAsHex.parse(query.slice(2, 4)) ?? 0x00,
      b: parseAsHex.parse(query.slice(4)) ?? 0x00
    }
  },
  serialize({ r, g, b }) {
    return (
      parseAsHex.serialize(r) +
      parseAsHex.serialize(g) +
      parseAsHex.serialize(b)
    )
  }
})
  // Eg: set common options directly
  .withOptions({ history: 'push' })

// Or on usage:
useQueryState(
  'tribute',
  hexColorSchema.withDefault({
    r: 0x66,
    g: 0x33,
    b: 0x99
  })
)
```

Note: see this example running in the [hex-colors demo](<./packages/docs/src/app/playground/(demos)/hex-colors/page.tsx>).

## Multiple Queries (batching)

You can call as many state update function as needed in a single event loop
tick, and they will be applied to the URL asynchronously:

```ts
const MultipleQueriesDemo = () => {
  const [lat, setLat] = useQueryState('lat', parseAsFloat)
  const [lng, setLng] = useQueryState('lng', parseAsFloat)
  const randomCoordinates = React.useCallback(() => {
    setLat(Math.random() * 180 - 90)
    setLng(Math.random() * 360 - 180)
  }, [])
}
```

If you wish to know when the URL has been updated, and what it contains, you can
await the Promise returned by the state updater function, which gives you the
updated URLSearchParameters object:

```ts
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
})
```

<details>
<summary><em>Implementation details (Promise caching)</em></summary>

The returned Promise is cached until the next flush to the URL occurs,
so all calls to a setState (of any hook) in the same event loop tick will
return the same Promise reference.

Due to throttling of calls to the Web History API, the Promise may be cached
for several ticks. Batched updates will be merged and flushed once to the URL.
This means not every setState will reflect to the URL, if another one comes
overriding it before flush occurs.

The returned React state will reflect all set values instantly,
to keep UI responsive.

---

</details>

## `useQueryStates`

For query keys that should always move together, you can use `useQueryStates`
with an object containing each key's type:

```ts
import { useQueryStates, parseAsFloat } from 'nuqs'

const [coordinates, setCoordinates] = useQueryStates(
  {
    lat: parseAsFloat.withDefault(45.18),
    lng: parseAsFloat.withDefault(5.72)
  },
  {
    history: 'push'
  }
)

const { lat, lng } = coordinates

// Set all (or a subset of) the keys in one go:
const search = await setCoordinates({
  lat: Math.random() * 180 - 90,
  lng: Math.random() * 360 - 180
})
```

## Loaders

To parse search params as a one-off operation, you can use a **loader function**:

```tsx
import { createLoader } from 'nuqs' // or 'nuqs/server'

const searchParams = {
  q: parseAsString,
  page: parseAsInteger.withDefault(1)
}

const loadSearchParams = createLoader(searchParams)

const { q, page } = loadSearchParams('?q=hello&page=2')
```

It accepts various types of inputs (strings, URL, URLSearchParams, Request, Promises, etc.). [Read more](https://nuqs.dev/docs/server-side#loaders)

See the [server-side parsing demo](<./packages/docs/src/app/playground/(demos)/pagination>)
for a live example showing how to reuse parser configurations between
client and server code.

## Accessing searchParams in Server Components

If you wish to access the searchParams in a deeply nested Server Component
(ie: not in the Page component), you can use `createSearchParamsCache`
to do so in a type-safe manner.

> Note: parsers **don't validate** your data. If you expect positive integers
> or JSON-encoded objects of a particular shape, you'll need to feed the result
> of the parser to a schema validation library, like [Zod](https://zod.dev).

```tsx
// searchParams.ts
import {
  createSearchParamsCache,
  parseAsInteger,
  parseAsString
} from 'nuqs/server'
// Note: import from 'nuqs/server' to avoid the "use client" directive

export const searchParamsCache = createSearchParamsCache({
  // List your search param keys and associated parsers here:
  q: parseAsString.withDefault(''),
  maxResults: parseAsInteger.withDefault(10)
})

// page.tsx
import { searchParamsCache } from './searchParams'

export default function Page({
  searchParams
}: {
  searchParams: Record<string, string | string[] | undefined>
}) {
  // ⚠️ Don't forget to call `parse` here.
  // You can access type-safe values from the returned object:
  const { q: query } = searchParamsCache.parse(searchParams)
  return (
    <div>
      <h1>Search Results for {query}</h1>
      <Results />
    </div>
  )
}

function Results() {
  // Access type-safe search params in children server components:
  const maxResults = searchParamsCache.get('maxResults')
  return <span>Showing up to {maxResults} results</span>
}
```

The cache will only be valid for the current page render
(see React's [`cache`](https://react.dev/reference/react/cache) function).

Note: the cache only works for **server components**, but you may share your
parser declaration with `useQueryStates` for type-safety in client components:

```tsx
// searchParams.ts
import { parseAsFloat, createSearchParamsCache } from 'nuqs/server'

export const coordinatesParsers = {
  lat: parseAsFloat.withDefault(45.18),
  lng: parseAsFloat.withDefault(5.72)
}
export const coordinatesCache = createSearchParamsCache(coordinatesParsers)

// page.tsx
import { coordinatesCache } from './searchParams'
import { Server } from './server'
import { Client } from './client'

export default async function Page({ searchParams }) {
  await coordinatesCache.parse(searchParams)
  return (
    <>
      <Server />
      <Suspense>
        <Client />
      </Suspense>
    </>
  )
}

// server.tsx
import { coordinatesCache } from './searchParams'

export function Server() {
  const { lat, lng } = coordinatesCache.all()
  // or access keys individually:
  const lat = coordinatesCache.get('lat')
  const lng = coordinatesCache.get('lng')
  return (
    <span>
      Latitude: {lat} - Longitude: {lng}
    </span>
  )
}

// client.tsx
// prettier-ignore
;'use client'

import { useQueryStates } from 'nuqs'
import { coordinatesParsers } from './searchParams'

export function Client() {
  const [{ lat, lng }, setCoordinates] = useQueryStates(coordinatesParsers)
  // ...
}
```

## Serializer helper

To populate `<Link>` components with state values, you can use the `createSerializer`
helper.

Pass it an object describing your search params, and it will give you a function
to call with values, that generates a query string serialized as the hooks would do.

Example:

```ts
import {
  createSerializer,
  parseAsInteger,
  parseAsIsoDateTime,
  parseAsString,
  parseAsStringLiteral
} from 'nuqs/server'

const searchParams = {
  search: parseAsString,
  limit: parseAsInteger,
  from: parseAsIsoDateTime,
  to: parseAsIsoDateTime,
  sortBy: parseAsStringLiteral(['asc', 'desc'])
}

// Create a serializer function by passing the description of the search params to accept
const serialize = createSerializer(searchParams)

// Then later, pass it some values (a subset) and render them to a query string
serialize({
  search: 'foo bar',
  limit: 10,
  from: new Date('2024-01-01'),
  // here, we omit `to`, which won't be added
  sortBy: null // null values are also not rendered
})
// ?search=foo+bar&limit=10&from=2024-01-01T00:00:00.000Z
```

### Base parameter

The returned `serialize` function can take a base parameter over which to
append/amend the search params:

```ts
serialize('/path?baz=qux', { foo: 'bar' }) // /path?baz=qux&foo=bar

const search = new URLSearchParams('?baz=qux')
serialize(search, { foo: 'bar' }) // ?baz=qux&foo=bar

const url = new URL('https://example.com/path?baz=qux')
serialize(url, { foo: 'bar' }) // https://example.com/path?baz=qux&foo=bar

// Passing null removes existing values
serialize('?remove=me', { foo: 'bar', remove: null }) // ?foo=bar
```

## Parser type inference

To access the underlying type returned by a parser, you can use the
`inferParserType` type helper:

```ts
import { parseAsInteger, type inferParserType } from 'nuqs' // or 'nuqs/server'

const intNullable = parseAsInteger
const intNonNull = parseAsInteger.withDefault(0)

inferParserType<typeof intNullable> // number | null
inferParserType<typeof intNonNull> // number
```

For an object describing parsers (that you'd pass to `createSearchParamsCache`
or to `useQueryStates`, `inferParserType` will
return the type of the object with the parsers replaced by their inferred types:

```ts
import { parseAsBoolean, parseAsInteger, type inferParserType } from 'nuqs' // or 'nuqs/server'

const parsers = {
  a: parseAsInteger,
  b: parseAsBoolean.withDefault(false)
}

inferParserType<typeof parsers>
// { a: number | null, b: boolean }
```

## Testing

Since nuqs v2, you can use a testing adapter to unit-test components using
`useQueryState` and `useQueryStates` in isolation, without needing to mock
your framework or router.

Here's an example using Testing Library and Vitest:

```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(<CounterButton />, {
    // Setup the test by passing initial search params / querystring,
    // and give it a function to call on URL updates
    wrapper: ({ children }) => (
      <NuqsTestingAdapter searchParams="?count=42" onUrlUpdate={onUrlUpdate}>
        {children}
      </NuqsTestingAdapter>
    )
  })
  // 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')
})
```

See [#259](https://github.com/47ng/nuqs/issues/259) for more testing-related discussions.

## Debugging

You can enable debug logs in the browser by setting the `debug` item in localStorage
to `nuqs`, and reload the page.

```js
// In your devtools:
localStorage.setItem('debug', 'nuqs')
```

> Note: unlike the `debug` package, this will not work with wildcards, but
> you can combine it: `localStorage.setItem('debug', '*,nuqs')`

Log lines will be prefixed with `[nuqs]` for `useQueryState` and `[nuq+]` for
`useQueryStates`, along with other internal debug logs.

User timings markers are also recorded, for advanced performance analysis using
your browser's devtools.

Providing debug logs when opening an [issue](https://github.com/47ng/nuqs/issues)
is always appreciated. 🙏

### SEO

If your page uses query strings for local-only state, you should add a
canonical URL to your page, to tell SEO crawlers to ignore the query string
and index the page without it.

In the app router, this is done via the metadata object:

```ts
import type { Metadata } from 'next'

export const metadata: Metadata = {
  alternates: {
    canonical: '/url/path/without/querystring'
  }
}
```

If however the query string is defining what content the page is displaying
(eg: YouTube's watch URLs, like `https://www.youtube.com/watch?v=dQw4w9WgXcQ`),
your canonical URL should contain relevant query strings, and you can still
use your parsers to read it, and to serialize the canonical URL:

```ts
// page.tsx
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<typeof youTubeSearchParams> = {
  videoId: 'v'
}
const loadYouTubeSearchParams = createLoader(youTubeSearchParams, {
  urlKeys: youTubeUrlKeys
})
const serializeYouTubeSearchParams = createSerializer(youTubeSearchParams, {
  urlKeys: youTubeUrlKeys
})

// --

type Props = {
  searchParams: Promise<SearchParams>
}

export async function generateMetadata({
  searchParams
}: Props): Promise<Metadata> {
  const { videoId } = await loadYouTubeSearchParams(searchParams)
  if (!videoId) {
    notFound()
  }
  return {
    alternates: {
      canonical: serializeYouTubeSearchParams('/watch', { videoId })
      // /watch?v=dQw4w9WgXcQ
    }
  }
}
```

### Lossy serialization

If your serializer loses precision or doesn't accurately represent
the underlying state value, you will lose this precision when
reloading the page or restoring state from the URL (eg: on navigation).

Example:

```ts
const geoCoordParser = {
  parse: parseFloat,
  serialize: v => v.toFixed(4) // Loses precision
}

const [lat, setLat] = useQueryState('lat', geoCoordParser)
```

Here, setting a latitude of 1.23456789 will render a URL query string
of `lat=1.2345`, while the internal `lat` state will be correctly
set to 1.23456789.

Upon reloading the page, the state will be incorrectly set to 1.2345.

## License

[MIT](https://github.com/47ng/nuqs/blob/next/LICENSE)

Made with ❤️ by [François Best](https://francoisbest.com)

Using this package at work ? [Sponsor me](https://github.com/sponsors/franky47)
to help with support and maintenance.

<div>
nuqs is part of the &nbsp;<a href="https://vercel.com/oss"><img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge.svg" /></a>&nbsp;<small><a href="https://vercel.com/blog/spring25-oss-program">(spring 2025 cohort)</a></small>
</div>

<br/>

![Project analytics and stats](https://repobeats.axiom.co/api/embed/3ee740e4729dce3992bfa8c74645cfebad8ba034.svg 'Repobeats analytics image')


================================================
FILE: errors/NUQS-101.md
================================================
# This package is ESM only.

Since version 2.0.0, `nuqs` is now an [ESM-only package](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).

## Probable cause

You may have encountered this error when trying to import `nuqs` in a CommonJS
environment, like Jest or ESLint.

## Possible solutions

If you cannot update your project to use ESM (which would be the most future-proof
solution), please refer to the following guides:

### Jest

See the [testing adapter documentation](https://nuqs.dev/docs/testing#jest-and-esm)
for its configuration with Jest.

### ESLint

See issue [#691](https://github.com/47ng/nuqs/issues/691) for more details.

### Something else?

If you are encountering this error in a different context, please
[open an issue](https://github.com/47ng/nuqs/issues/new/choose) with details about
your setup (a reproduction repository would be even better).


================================================
FILE: errors/NUQS-303.md
================================================
# Multiple adapter contexts detected

## Probable cause

This error occurs in [debug mode](https://nuqs.dev/docs/debugging) in
certain monorepo setups where references of the adapter context aren't the same
in different packages, and cause a [`NUQS-404 - nuqs requires an adapter to work with your framework`](./NUQS-404.md) error.

## Root cause

As described in the [React docs](https://react.dev/reference/react/useContext#my-component-doesnt-see-the-value-from-my-provider), this can happen with Context providers (which
is what adapters are) being re-created in different modules and causing different
references being used for a provider and consumers.

## Possible solutions

See issue [#798](https://github.com/47ng/nuqs/issues/798) for more details.


================================================
FILE: errors/NUQS-404.md
================================================
# `nuqs` requires an adapter to work with your framework

## Probable cause

You haven't wrapped the components calling `useQueryState(s)` with
an adapter.

[Adapters](https://nuqs.dev/docs/adapters) are based on React Context,
and provide nuqs hooks with the interfaces to work with your framework:
reacting to URL changes, and calling your router when you update your state.

## Possible solutions

Follow the setup instructions to import and wrap your application
using a suitable adapter:

- [Next.js (app router)](https://nuqs.dev/docs/adapters#nextjs-app-router)
- [Next.js (pages router)](https://nuqs.dev/docs/adapters#nextjs-pages-router)
- [React SPA (eg: with Vite)](https://nuqs.dev/docs/adapters#react-spa)
- [Remix](https://nuqs.dev/docs/adapters#remix)
- [React Router v6](https://nuqs.dev/docs/adapters#react-router-v6)
- [React Router v7](https://nuqs.dev/docs/adapters#react-router-v7)
- [TanStack Router](https://nuqs.dev/docs/adapters#tanstack-router)

### Test adapter

If you encounter this error outside of the browser, like in a test
runner (eg: Vitest or Jest), you may use the [testing adapter](https://nuqs.dev/docs/testing)
from `nuqs/adapters/testing` to mock the initial search params and access
setup/assertion testing facilities.

### Monorepo setups

This error can also occur in monorepo setups where components using nuqs hooks
are in different packages resolving to different `nuqs` versions,
leading to different context references being used.

If you [enable debugging](https://nuqs.dev/docs/debugging), you might see a
[`NUQS-303 - Multiple adapter contexts detected`](./NUQS-303.md) error, confirming
this hypothesis.

Make sure that all packages resolve to the same version
of `nuqs` to prevent this issue from arising. See issue
[#798](https://github.com/47ng/nuqs/issues/798) for more details and
possible solutions.


================================================
FILE: errors/NUQS-409.md
================================================
# Multiple versions of the library are loaded

This error occurs if two different versions of `nuqs` are
loaded in the same application.

This may happen if you are using a package that embeds `nuqs` and
you are also using `nuqs` directly.

## Possible Solutions

Inspect your dependencies for duplicate versions of `nuqs` and
use the `resolutions` field in `package.json` to force all dependencies
to use the same version.


================================================
FILE: errors/NUQS-414.md
================================================
# Max Safe URL Length Exceeded

This error occurs if your URL length exceeds 2,000 characters.

There are varying browser limitations for max URL lengths, [read more](https://nuqs.dev/docs/limits#max-url-lengths).

URLs that are too long might break in some browsers, or not be able to be
processed by some servers.

## Possible Solutions

Keeping your URLs short is a good practice: not all state has to live in the URL.

- Server state/data is best managed in a local cache like TanStack Query or SWR.
- Transient state (that doesn't need persisting or sharing) can be managed in local state.
- Device-persistent state can be managed in local storage.

When deciding to put state in the URL, ask yourself:

- Do I need it to persist across page refresh?
- Do I need to share it with others?
- Do I need to link to it from other places?
- Do I need to be able to bookmark it?
- Do I need to be able to use the Back/Forward buttons to navigate to it?
- Is it always going to be a small amount of data?

If the answer to any of these questions is no, then you might want to consider
an alternative state storage solution.


================================================
FILE: errors/NUQS-422.md
================================================
# Invalid Options Combination.

This warning will show up if you combine `shallow: true` (the default) and `limitUrlUpdates: debounce` options.

Debounce only makes sense for server-side data fetching, the returned client state is always updated **immediately**, so combining `limitUrlUpdates: debounce` with `shallow: true` will not work as expected.

If you are fetching client-side, you’ll want to debounce the state returned by the hooks instead (using a 3rd party `useDebounce` utility hook).

## Solution

- Set `shallow: false` to allow debounce to work properly, check the [documentation](https://nuqs.dev/docs/options#debounce) for more information.


================================================
FILE: errors/NUQS-429.md
================================================
# URL update rate-limited by the browser

This error occurs when too many URL updates are attempted in a short period of
time. For example, connecting a query state to a text input that updates on
every keypress, or a slider (`<input type="range">`).

## Possible Solutions

The library has a built-in throttling mechanism, that can be configured per
instance. See the [throttling](https://github.com/47ng/nuqs#throttling)
docs for more information.

## Safari

Safari has a very low rate-limit on URL updates: 100 updates per 30 seconds (or per 10 seconds on Safari 17 and above).


================================================
FILE: errors/NUQS-500.md
================================================
# Empty Search Params Cache

This error shows up on the server when trying to access a searchParam from
a cache created with `createSearchParamsCache`, but when the cache was not
properly populated at the top of the page.

## A note on layouts

The error can also occur if your server component consuming the search params
cache is mounted in a **layout** component. Those don't receive search params as
they are not re-rendered when the page renders.

In this case, your only option is to turn the server component into a client
component, and read the search params with `useQueryStates`. You can
[feed it the same parser object](https://github.com/47ng/nuqs#accessing-searchparams-in-server-components)
you used to create the cache, and it you'll get the same
type safety.

## Possible Solution

Run the `parse` method and feed it the page's `searchParams`:

```tsx
// page.tsx
import {
  createSearchParamsCache,
  parseAsInteger,
  parseAsString,
  type SearchParams
} from 'nuqs/server'

const cache = createSearchParamsCache({
  q: parseAsString,
  maxResults: parseAsInteger.withDefault(10)
})

export default function Page({
  searchParams
}: {
  searchParams: Promise<SearchParams>
}) {
  // ⚠️ Don't forget to call `parse` here:
  const { q: query } = await cache.parse(searchParams)
  return (
    <div>
      <h1>Search Results for {query}</h1>
      <Results />
    </div>
  )
}

function Results() {
  // In order to get search params from child server components:
  const maxResults = cache.get('maxResults')
  return <span>Showing up to {maxResults} results</span>
}
```


================================================
FILE: errors/NUQS-501.md
================================================
# Search params cache already populated

This error occurs when a [search params cache](https://github.com/47ng/nuqs#accessing-searchparams-in-server-components)
is being fed searchParams more than once.

Internally, the cache object will be frozen for the duration of the page render
after having been populated. This is to prevent search params from being modified
while the page is being rendered.

## Solutions

Look into the stack trace where the error occurred and remove the second call to
`parse` that threw the error.


================================================
FILE: package.json
================================================
{
  "name": "nuqs-monorepo",
  "version": "0.0.0",
  "private": true,
  "license": "MIT",
  "author": {
    "name": "François Best",
    "email": "contact@francoisbest.com",
    "url": "https://francoisbest.com"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/47ng/nuqs"
  },
  "scripts": {
    "dev": "turbo run dev",
    "build": "turbo run build",
    "test": "turbo run test --log-order=stream",
    "prepare": "husky",
    "lint": "pnpm run -w --parallel --stream '/^lint:/'",
    "lint:prettier": "prettier --check ./packages/nuqs/src/**/*.ts",
    "lint:sherif": "sherif"
  },
  "devDependencies": {
    "@commitlint/config-conventional": "^20.4.1",
    "commitlint": "^20.4.1",
    "husky": "^9.1.7",
    "prettier": "3.6.2",
    "publint": "^0.3.17",
    "semantic-release": "^25.0.3",
    "sherif": "^1.10.0",
    "turbo": "^2.8.2",
    "typescript": "^5.9.3"
  },
  "packageManager": "pnpm@10.28.2",
  "prettier": {
    "arrowParens": "avoid",
    "semi": false,
    "singleQuote": true,
    "tabWidth": 2,
    "trailingComma": "none",
    "useTabs": false
  },
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
      "pre-push": "pnpm run lint"
    }
  },
  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ],
    "rules": {
      "type-enum": [
        2,
        "always",
        [
          "build",
          "chore",
          "ci",
          "clean",
          "doc",
          "feat",
          "fix",
          "perf",
          "ref",
          "revert",
          "style",
          "test"
        ]
      ],
      "subject-case": [
        0,
        "always",
        "sentence-case"
      ],
      "body-leading-blank": [
        2,
        "always",
        true
      ]
    }
  }
}


================================================
FILE: packages/docs/.gitignore
================================================
# deps
/node_modules

# generated content
_map.ts
.contentlayer
.source

# test & build
/coverage
/.next/
/out/
/build
*.tsbuildinfo

# misc
.DS_Store
*.pem
/.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# others
.env*.local
.vercel
next-env.d.ts
# Sentry Config File
.sentryclirc

# shadcn registry output
registry.json
public/r


================================================
FILE: packages/docs/README.md
================================================
# docs

This is a Next.js application generated with
[Fumadocs](https://github.com/fuma-nama/fumadocs).

Run development server:

```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```

Open http://localhost:3000 with your browser to see the result.

## Learn More

To learn more about Next.js and Next Docs, take a look at the following
resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
  features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs


================================================
FILE: packages/docs/components.json
================================================
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "src/app/globals.css",
    "baseColor": "zinc",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/src/components",
    "utils": "@/src/lib/utils"
  }
}


================================================
FILE: packages/docs/content/blog/2025.mdx
================================================
---
title: '2025'
description: A look back on an amazing year of OSS, meeting people, and milestones.
author: François Best
date: 2025-12-31
---

import { GitHubProfile } from '@/src/components/github-profile'
import { ReleaseContributionGraph } from '@/src/components/release-contribution-graph'

To say that **2025 was an incredible year** would be quite the understatement.

This wild ride started on the 3rd of January, when I learned my CFP for
[React Paris](https://react.paris) had been accepted.
Only 3 days after setting my yearly goal of speaking at a conference.
This, honestly, has been the highlight of this year: speaking at _not one_,
but _three_ prestigious conferences, and meeting a ton of people along the way.

For context, at the beginning of 2025, nuqs was one year old
(at least the rebranding from `next-usequerystate` on Jan 1st 2024),
and we had just [opened it up to the rest of the React ecosystem](/blog/nuqs-2)
a couple of months prior.

<ReleaseContributionGraph year={2025} />

The success it has encountered this year is mind-boggling:

- ⭐ Stars: 5500 → 9800 (+4300 in 2025)
- 📦 All-time NPM downloads: 7.5M → 41M (+33.5M in 2025)
- 💖 Sponsors: 5 (+2,245€) → 20 (+2,802€)
- 🫶 Sponsoring: 0 ($0) → 20 (-$3,316)

<Callout title="About the emoji 👀">
I'm writing this article by hand, without any help from AI.
I just like emoji. #SorryNotSorry
</Callout>


But open-source is not about code, it's about **people**.

It's a social graph of members of the community, contributors, maintainers, and sponsors.
And the increase of interest in nuqs has been a great opportunity for me
to meet a lot of people, mainly through conferences.

## Conferences

### React Paris

It was my first time speaking at a big conference, and the speakers lineup was amazing:

- <GitHubProfile name="Kent C Dodds" handle="kentcdodds"/>
- <GitHubProfile name="Tejas Kumar" handle="TejasQ"/>
- <GitHubProfile name="David Khourshid" handle="DavidKPiano" />
- <GitHubProfile name="Aurora Scharff" handle="aurorascharff" />
- <GitHubProfile name="Dominik Dorfmeister" handle="TkDodo" />
- And many more…

I had been chatting with <GitHubProfile name="Aurora" handle="aurorascharff" url="https://aurorascharff.no"/> before the conference about some optimistic update problems
she discovered with nuqs, and was very pleased to learn that she incorporated it in
[her talk](https://www.youtube.com/watch?v=dA-8FY5xlbk&list=PL53Z0yyYnpWitP8Zv01TSEQmKLvuRh_Dj&index=12)
(happening right after mine).
The biggest surprise though was that <GitHubProfile name="David" handle="DavidKPiano" url="https://stately.ai/"/> (whose talk was just before mine)
also talked about nuqs (and Aurora's) in his own talk,
["Goodbye useState"](https://www.youtube.com/watch?v=aGkscOKWQvQ&list=PL53Z0yyYnpWitP8Zv01TSEQmKLvuRh_Dj&index=18).
A lovely program scheduling coincidence.

<iframe
  src="https://www.youtube-nocookie.com/embed/U__Rwsp8v78?si=sQgg-HJTMoy_mt7K&amp;start=34"
  title="YouTube video player"
  frameBorder="0"
  allow="autoplay; encrypted-media; picture-in-picture; web-share"
  referrerPolicy="strict-origin-when-cross-origin"
  allowFullScreen
  className='aspect-video w-full max-w-2xl mx-auto mb-12'
/>

I also met <GitHubProfile name="Dominik" handle="TkDodo" url="https://tkdodo.eu"/> IRL for the first time.
He told me he had just joined Sentry and wanted to use nuqs there, for which we needed to support a few things.
He graciously contributed those changes to the core package, and now Sentry
is in the top 5 most popular OSS repos using nuqs 🙌 Thank you, Dominik! 🫶

### Next.js Conf

Back in April, nuqs joined the [Vercel OSS Program](https://vercel.com/open-source-program). My interest for it wasn't the credits
from partners (I still haven't claimed any of them, as I don't need them), but the **community** of OSS builders it brings together.

I was then invited to speak about nuqs at Next.js Conf in San Francisco. Due to a series of unfortunate events,
this experience could have been smoother. Maybe one day I'll write about the bad parts of it.

But let's focus on the good ones:

- Along with two teammates from Brazil & Colombia, we won the pre-conf hackathon organised by [Clerk](https://clerk.com/) & [CodeTV](https://www.youtube.com/@codetv-dev).
Those gains helped me sign the [Open Source Pledge](/blog/open-source-pledge).

- My talk was very well received, and again, meeting people IRL that I had been chatting with online is great. The hallway track really is the best part of conferences.

<iframe
  src="https://www.youtube-nocookie.com/embed/qpczQVJMG1Y"
  title="YouTube video player"
  frameBorder="0"
  allow="autoplay; encrypted-media; picture-in-picture; web-share"
  referrerPolicy="strict-origin-when-cross-origin"
  allowFullScreen
  className='aspect-video w-full max-w-2xl mx-auto mb-12'
/>

### React Advanced London

Just one month after SF, I gave the same talk in London. Same-ish: the time kept getting shorter,
and I kept on adding more into it, so I ended up speaking super fast! 😅

It also went very well, the room was packed, and the live Q&A on stage at the end was a very nice way to interact
with the audience. Thanks <GitHubProfile name="Amber Shand" handle="amberleeshand" url="https://www.ambershand.co.uk/" /> for MCing! 🦆🦆😉

## The Horde

Of all the people I met online this year, one stands out: <GitHubProfile name="OrcDev" handle="TheOrcDev" url="https://orcdev.com"/>,
who was one of the first YouTubers to spread the word about nuqs.

We became friends, convinced each other to apply for conferences (he also gave his first talk this year ⚔️),
and started growing a community around our projects, composed of fellow OSS maintainers & builders.

This community is called [The Horde](https://join.thehorde.dev), and its purpose is to help devs starting with open source
get visibility, help, and pool resources for a greater reach. All in orcish retro-gaming style. No warrior fights alone. ⚔️

## 2026

So what are the plans for the new year?

On the personal side, I have been neck deep in [client work](mailto:consulting@francoisbest.com)
for the last few months, so the backlog of issues & PRs has been growing. Big thanks to regular contributors like <GitHubProfile name="Dominik Koch" handle="mezotv" url="https://dominikkoch.dev/"/> & <GitHubProfile handle="TkDodo" />
for their help 🫶, I'm also going to need to focus a bit of my time on nuqs to bring it back to a satisfying state:
a solid base on which we can plan the next big thing.

For this project to be sustainable, it needs a couple of things:

1. Solid funding
2. A community of contributors & co-maintainers

import { InlineSponsorsList } from '@/src/app/(pages)/_landing/sponsors'

Big thanks to the [💖 sponsors](https://github.com/sponsors/franky47) who are making this project possible:

<InlineSponsorsList className='mb-12'/>

A few goals for this year:
- Improve TanStack Router / Start support (even though you don't _need_ nuqs for it,
I don't see why it shouldn't be supported as well as the other frameworks, to the extent of what's possible).
- Rewrite the core to a single store so we can ship devtools, and unlock performance improvement and DX.
This could theoretically also unlock Solid/Svelte/Vue implementations, but the React ecosystem brings already enough work to maintain.
- Ship nuqs@3.0.0 with runtime Standard Schema validation

### Workshop

Talks at conferences are great for introducing nuqs (I particularly like live-coding
to tell a story through code), but ~30 minutes is usually too short for deep dives and
studing patterns in real-life apps.

So this year I'm working on a workshop around nuqs & type-safe URL state in general:

- Why you need URL state (and when not to use it)
- How to implement it in your app in a way that scales
- How to maintain it over time

This workshop is aimed at teams that maintain large applications with complex URL state logic,
so feel free to [contact me](mailto:workshop@francoisbest.com) if your company is interested.

### Side quests

After setting up my office for recording [YouTube videos](https://www.youtube.com/@47ng-dev)
(a whopping 5 videos published this year 😅) and streaming [live on Twitch](https://www.twitch.tv/francoisbest),
and helping friends like <GitHubProfile name="OrcDev" handle="TheOrcDev" url="https://www.youtube.com/@orcdev"/>, <GitHubProfile handle="AlemTuzlak" name="Alem Tuzlak" url="https://www.youtube.com/@alemtuzlak"/> (maintainer of TanStack AI & Devtools),
and <GitHubProfile handle="varkoff" name="Virgile Rietsch" url="https://www.youtube.com/@Virgile-Rietsch" /> with their audio setup, I realised something:

**Most people starting on YouTube have a terrible sound.**

It's a shame, because their content would be otherwise great, but no matter if you shoot in 4K,
if you sound like you're in the middle of an airport hall, I'm going to skip to the next video.

So I want to help change that. I've got a few techniques (gathered from my 8 years in the pro-audio industry)
to help folks get a decent result out of the hardware they already have, without breaking the bank,
and I'm working on a **mini-course** to help increase retention rates on videos through better sound.

## Wrapping up

I wish you a Happy New Year: may your projects be successful, and may you find friends along the way.
Because in this day & age of ubiquitous AI, it's easy to forget why we do this job: **for people**.


================================================
FILE: packages/docs/content/blog/beware-the-url-type-safety-iceberg.components.tsx
================================================
'use client'

import { useState } from 'react'

const states = {
  pagination: {
    pageIndex: 1,
    pageSize: 50
  },
  filters: [
    {
      id: 'genre',
      value: 'fantasy'
    }
  ],
  orderBy: {
    id: 'releaseYear',
    desc: false
  }
}

const passThrough = <T,>(x: T) => x

export function URLComparison() {
  const [highlight, setHighlight] = useState(false)
  const [encoding, setEncoding] = useState(true)
  const keyClass = highlight ? 'text-pink-700 dark:text-pink-400' : ''
  const valueClass = highlight ? 'text-sky-700 dark:text-sky-400' : ''
  const encode = encoding ? encodeURIComponent : passThrough
  return (
    <div className="rounded-md border border-dashed px-2 pt-2">
      <div className="flex gap-4 pl-1 text-sm">
        <label className="flex gap-2">
          <input
            type="checkbox"
            checked={highlight}
            onChange={e => setHighlight(e.target.checked)}
          />
          Highlighting
        </label>
        <label className="flex gap-2">
          <input
            type="checkbox"
            checked={encoding}
            onChange={e => setEncoding(e.target.checked)}
          />
          Encoding
        </label>
      </div>
      <ol className="space-y-4">
        <li className="break-all">
          {'https://example.com'}?<span className={keyClass}>page</span>=
          <span className={valueClass}>1</span>&
          <span className={keyClass}>size</span>=
          <span className={valueClass}>50</span>&
          <span className={keyClass}>filters</span>=
          <span className={valueClass}>genre:fantasy</span>&
          <span className={keyClass}>sort</span>=
          <span className={valueClass}>releaseYear:asc</span>
        </li>
        <li className="break-all">
          {'https://example.com'}?<span className={keyClass}>pagination</span>=
          <span className={valueClass}>
            {encode(JSON.stringify(states.pagination))}
          </span>
          &<span className={keyClass}>filters</span>=
          <span className={valueClass}>
            {encode(JSON.stringify(states.filters))}
          </span>
          &<span className={keyClass}>orderBy</span>=
          <span className={valueClass}>
            {encode(JSON.stringify(states.orderBy))}
          </span>
        </li>
      </ol>
    </div>
  )
}


================================================
FILE: packages/docs/content/blog/beware-the-url-type-safety-iceberg.mdx
================================================
---
title: Beware The URL Type-Safety Iceberg
description: Type-safe URL state is only the visible part. There are more dangers below.
author: François Best
date: 2025-06-10
---

The nuqs tagline, _"**type-safe search params** state manager for React"_, only represents
a small fraction of what nuqs does under the hood. Type-safety is only the tip of the iceberg.
There are hidden dangers beneath the surface that you (or, better, your tools) need to be aware of.

## Read vs Write

One of the first things people do when they want type-safe URL state is to
bring in validation libraries (Zod, Valibot, ArkType, anything [Standard Schema](https://standardschema.dev/) compliant)
to parse `URLSearchParams{:ts}` into valid data types they can use in their apps.

That's **read** type-safety, and it is fairly easy to achieve.

You could stop here and wonder why you'd need another third-party library, until
you need to **write** search params with _complex_ state. Anything that doesn't
trivially stringify using `.toString(){:ts}` will need a _serialisation_ step that matches
the parsing <small>(math nerds call this property _bijectivity_)</small>.

Validation libraries don't provide the reverse transform from an object or data type
back to the string it got transformed from. To address this, nuqs comes with [built-in parsers](/docs/parsers/built-in)
for common data types, but you can also [make your own](/docs/parsers/making-your-own)
to give your complex data types a beautiful, **compact** representation in the URL.

Compactness here is the important property: URLs have a size limit, much like local storage
or cookies.

While 2000 characters is generally considered safe, the HTTP spec allows a bit more headroom at 8KB, but
practical limitations will be those of the medium you share your URL through, and
the (un)willingness of users to click very long links. Remember:

> The URL is the first piece of UI your users will see. Design it as such.

See for yourself: which link would you rather click on?

import { URLComparison } from './beware-the-url-type-safety-iceberg.components'
import { Suspense } from 'react'

<Suspense fallback={
  <div className="rounded-md border border-dashed px-2 pt-2">
    <div className="flex gap-4 pl-1 text-sm text-gray-600 dark:text-gray-400 animate-pulse">
      <label className='flex gap-2'>
        <input type="checkbox" disabled />
        Highlighting
      </label>
      <label className="flex gap-2">
        <input type="checkbox" disabled checked />
        Encoding
      </label>
    </div>
    <ol className="space-y-4">
      <li className="break-all">
        {'https://example.com?page=1&size=50&filters=genre:fantasy&sort=releaseYear:asc'}
      </li>
      <li className="break-all">
        {'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'}
      </li>
    </ol>
  </div>
}>
  <URLComparison/>
</Suspense>

<Callout title="Tip: what state goes in the URL?">
  Only store state in the URL that you want to **share with others** (including your future self, with bookmarks
  and history navigation).

  Putting state there only because it's convenient for it to persist across page reloads will likely
  make you overuse this pattern.
</Callout>

## Deserialise, parse, validate

Validation libraries still have a very important purpose: making sure your state is
**runtime-safe**. Even after deserialisation into the correct data type,
there may be invalid _values_ you want to avoid, and that you cannot represent with
static typing alone. Things like:

- A number between -90/+90 or -180/+180 for latitude/longitude coordinates
- A string formatted in a certain way (like an email or a UUID)
- A date greater than a given epoch

On read, validation should occur **after** deserialisation, on a data type relatively close
to the desired output (which is ensured by parsing).

Similarly, on write, validation should occur **before** serialisation, to
make sure invalid states don't get persisted to the URL.


## Time Safety

80% of the nuqs codebase does not deal with _type safety_, but **time safety**.

One of the lesser known issues with the
[History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API)
(that most routers use to update the URL without doing a full page load) is that
**browsers rate-limit URL updates**, for security reasons.

Calling updates too quickly will throw an error, potentially crashing your app
in the process.

Not all browsers are equal on this rate limiting: Chrome and Firefox allow about 50ms between calls
to be safe, but Safari has much stricter limits, and requires about 120ms between calls.

This issue surfaces when binding URL state to a high-frequency input, like a text box
`<input type="text">{:html}` or a slider `<input type="range">{:html}`.

You could solve this by keeping inputs _uncontrolled_ and deferring the URL update to
a later time (after a debounce timeout or the press of a button), but controlled inputs have their
purpose. If you want to follow external URL updates to reset their state, or if other
parts of the React tree need this state, call `useQueryState(s){:ts}` anywhere you need
access to that shared state (the same way you would use a global state manager like Zustand, Jotai, etc.),
and nuqs will **lift the state _out_** into the URL for you.

Rather than requiring rigidity in userland, nuqs embraces browser limits and solves the time safety
problem with a **throttled queue** and **optimistic URL updates**.

This also allows **batching** state updates from different sources, and **stitching** them together
automatically, which is one of the most encountered pain points when doing this manually.

```ts
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)
}
```

<Callout>
  You might want to use [`useQueryStates{:ts}`](/docs/batching) for better type-safety when using
  related states.
</Callout>

The upcoming [debounce feature](https://github.com/47ng/nuqs/pull/900) makes this process
even more apparent, with the additional complexity of having to handle aborting pending updates
when the user navigates away from the page they're on. This prevents stale state updates from being
applied on the wrong pathname or overriding link state (last user action wins).

## Immutability

Once you've shared URLs out in the wild, they become **immutable**. But your application is anything but immutable.

The statefulness you introduce by adding URL state makes it akin to a database schema.
Each shared URL is an immutable database snapshot that your app needs to be able to process
throughout its lifetime, to honour the promise encoded in those links. But it should not
prevent you from making changes in the expected schema your app accepts.

Just like database schemas, we can handle this with **migrations**:

1. Capture old URLs with a middleware
2. Migrate the old state schema into what the app currently expects
3. Redirect to the updated URL to continue

We've [explored declarative ways](https://x.com/fortysevenfx/status/1842162844613112081) to do this,
but this is something that could benefit more than just nuqs users, so it may materialise
as a complementary package.

```ts
// Note: this is a hypothetical API.

const applyMigrations = createURLMigration([
  {
    // Transform /?hello=world to /?name=world
    type: "rename-key",
    from: "hello",
    to: "name",
  },
  {
    // Transform /?hello=world&bye-bye=gone to /?hello=world
    type: "remove-key",
    key: "bye-bye",
  },
  {
    // Convert /?date=2022-01-01T00:00:00Z to /?date=1640995200000
    type: "update-value",
    key: "date",
    action: (value) => {
      const date = parseAsIsoDateTime.parse(value);
      if (date === null) {
        return null;
      }
      return parseAsTimestamp.serialize(date);
    },
  },
  {
    type: "custom", // Full control (with great power…)
    action: (request) => {
      const searchParams = new URLSearchParams(request.nextUrl.searchParams);
      const value = parseAsFoo.parse(searchParams.get('foo'))
      searchParams.delete('foo')
      searchParams.set('bar', parseAsBar.serialize(value))
      return { applied: true, searchParams }
    },
  },
]);

export function middleware(request: NextRequest) {
  const result = applyMigrations(request);
  if (result.applied) {
    return result.response;
  }
  return NextReponse.next();
}
```

## Time Travel

When updating the URL, you can choose to either **replace** the current history entry with
the updated state, or **push** a new one (this is done with the
`history: 'push' | 'replace'{:ts}` [option](/docs/options#history) in nuqs).

Pushing a new history entry allows you to use the Back/Forward buttons of the browser as an
undo-redo feature, which looks like Redux Devtools' time travel state debugging.

But this comes at a price: you now have two sources of updates that can manipulate history:

1. The original UI element that triggered the update
2. The Back/Forward buttons

This is often encountered with a `?modalOpen=true` state, where the Back/Forward buttons
can conflict with the X button to close the modal. Depending on whether the user opened the
modal through the UI or landed on it via a link, the Back button might have different behaviours.

**Breaking the Back button** leads to a frustrating user experience, and handling it properly involves a few steps:

- Being aware that users can enter your app **at any state**
- From that state, they can use **either** the Back button or your UI
- Remember that Back/Forward is a contract for **navigation-like interactions**

The experimental [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API)
should hopefully make it easier to handle these cases in the future.

## Conclusion

Achieving type-safety for URL state is not the endgame, but it's the beginning of a journey:
there are other things that URL state management libraries and application code need to deal
with, to provide truly safe and durable state management.

This post is an excerpt of my talk at React Paris, watch it here for more details and tips:

<iframe
  src="https://www.youtube-nocookie.com/embed/U__Rwsp8v78?si=sQgg-HJTMoy_mt7K&amp;start=34"
  title="YouTube video player"
  frameBorder="0"
  allow="autoplay; encrypted-media; picture-in-picture; web-share"
  referrerPolicy="strict-origin-when-cross-origin"
  allowFullScreen
  className='aspect-video w-full max-w-2xl mx-auto'
/>


================================================
FILE: packages/docs/content/blog/nuqs-2.5-key-isolation.client.tsx
================================================
'use client'

import { Button } from '@/src/components/ui/button'
import { parseAsInteger, useQueryState } from 'nuqs'
import { NuqsAdapter } from 'nuqs/adapters/react'
import { useEffect, useLayoutEffect, useRef, useState } from 'react'

export function KeyIsolationStyles() {
  return (
    <style key="flash-fade-keyframes">{`
        :root {
          --flash-color: oklch(0.627 0.265 303.9); /* Tailwind purple-500 */
        }
        @keyframes flashOutline {
          0% {
            box-shadow: 0 0 6px 4px var(--flash-color);
          }
          100% {
            box-shadow: 0 0 0px 0px transparent;
          }
        }
        .flash-outline {
          animation: flashOutline 250ms ease-out both;
        }
      `}</style>
  )
}

export function DemoSkeleton() {
  return (
    <figure className="flex animate-pulse flex-wrap justify-around gap-8 rounded-md border border-dashed p-4">
      <ComponentSkeleton />
      <ComponentSkeleton />
    </figure>
  )
}

export function WithoutKeyIsolationDemo() {
  return (
    <figure className="flex flex-wrap justify-around gap-2 rounded-md border border-dashed p-2">
      <Component id="a" />
      <Component id="b" />
    </figure>
  )
}

export function WithKeyIsolationDemo() {
  const [hydrated, setHydrated] = useState(false)
  useEffect(() => {
    setHydrated(true)
  }, [])
  if (!hydrated) {
    return <DemoSkeleton />
  }
  return (
    <NuqsAdapter>
      <figure className="flex flex-wrap justify-around gap-2 rounded-md border border-dashed p-2">
        <Component id="c" />
        <Component id="d" />
      </figure>
    </NuqsAdapter>
  )
}

function Component({ id }: { id: string }) {
  const [count, setCount] = useQueryState(id, parseAsInteger.withDefault(0))
  const renders = useRef(0)
  renders.current += 1
  const wrapperRef = useRef<HTMLDivElement>(null)
  useLayoutEffect(() => {
    const div = wrapperRef.current
    if (!div) {
      return
    }
    div.classList.remove('flash-outline')
    div.offsetWidth // Trigger reflow to restart the animation
    div.classList.add('flash-outline')
  })

  return (
    <div className="rounded-xl p-1.5 [will-change:box-shadow]" ref={wrapperRef}>
      <Button
        onClick={() => setCount(c => c + 1)}
        className="min-w-42 tabular-nums"
      >
        Increment "{id}": {count}
      </Button>
    </div>
  )
}

function ComponentSkeleton() {
  return (
    <div className="rounded-xl p-1.5">
      <Button disabled className="min-w-42 tabular-nums">
        Loading demo...
      </Button>
    </div>
  )
}


================================================
FILE: packages/docs/content/blog/nuqs-2.5.mdx
================================================
---
title: nuqs 2.5
description: Debounce, Standard Schema, TanStack Router, Key isolation, Global defaults, and more…
author: François Best
date: 2025-08-22
---

nuqs@2.5.0 is available, try it now:

```npm
npm install nuqs@latest
```

It's a big release full of long-awaited features, bug fixes & improvements, including:

- ⏱️ [Debounce](#debounce): only send network requests once users stopped typing in search inputs
- ☑️ [Standard Schema](#standard-schema): connect validation & type inference to external tools (eg: tRPC)
- ⚡ [Key isolation](#key-isolation): only re-render components when their part of the URL changes
- 🏝️ [TanStack Router](#tanstack-router) support with type-safe routing _(🧪 experimental)_

## Debounce

While nuqs has always had a throttling system in place to adapt to [browers rate-limiting URL updates](/blog/beware-the-url-type-safety-iceberg#time-safety),
this system wasn't ideal for **high frequency inputs**, like `<input type="search">{:html}`, or `<input type="range">{:html}` sliders.

For those cases where the _final value_ is what matters, **debouncing** makes more sense than **throttling**.

<Callout title="Do I need debounce?">
  Debounce only makes sense for **server-side data fetching** (RSCs & loaders, when combined with [`shallow: false{:ts}`](#shallow)),
  to control when requests are made to the server. For example: it lets you avoid sending the first
  character on its own when typing in a search input, by waiting for the user to finish typing.

  The state returned by the hooks is always updated **immediately**: only the network requests
  sent to the server are debounced.

  If you are **fetching client-side** (eg: with TanStack Query), you'll want to debounce the
  returned state instead (using a 3rd party `useDebounce` utility hook).
</Callout>

You can now specify a new option, `limitUrlUpdates{:ts}`, that replaces `throttleMs{:ts}` and declares either a debouncing or throttling behaviour:

```tsx
// [!code word:limitUrlUpdates]
import { debounce, useQueryState } from 'nuqs'

function DebouncedSearchInput() {
  // Send updates to the server after 250ms of inactivity
  const [search, setSearch] = useQueryState('search', {
    defaultValue: '',
    shallow: false,
    limitUrlUpdates: debounce(250)
  })

  // You can still use controlled components:
  // the local state updates instantly.
  return (
    <input
      type="search"
      value={search}
      onChange={e => setSearch(e.target.value)}
    />
  )
}
```

Read the [complete documentation](/docs/options#rate-limiting-url-updates) for the API, explanations of what it does,
and a list of tips when working with search inputs _(you might not want to **always** debounce)_.

## Standard Schema

You can now use your **search params definitions objects**
(the ones you feed to
[`useQueryStates{:ts}`](/docs/batching#usequerystates),
[`createLoader{:ts}`](/docs/server-side#loaders) and
[`createSerializer{:ts}`](/docs/utilities#serializer-helper)) to derive a **Standard Schema validator**,
that you can use for basic runtime validation and type inference with other tools, like:
- tRPC, to validate procedure inputs when feeding them your URL state
- TanStack Router's `validateSearch{:ts}` ([see below](#tanstack-router))

```ts
// [!code word:validateSearchParams]
import {
  createStandardSchemaV1,
  parseAsInteger,
  parseAsString,
} from 'nuqs'

// 1. Define your search params as usual
export const searchParams = {
  searchTerm: parseAsString.withDefault(''),
  maxResults: parseAsInteger.withDefault(10)
}

// 2. Create a Standard Schema compatible validator
export const validateSearchParams = createStandardSchemaV1(searchParams)

// 3. Use it with other tools, like tRPC:
router({
  search: publicProcedure.input(validateSearchParams).query(...)
})
```

Read the [complete documentation](/docs/utilities#standard-schema) for the options you can pass in.

## Key isolation

Also known as _fine grained subscriptions_, and pioneered by TanStack Router, key isolation is the idea
that components listening to a search param key in the URL should **only re-render when the value for that
key changes**.

Without key isolation, any change of the URL re-renders every component listening to it.

Take a look at those two counter buttons,
and how clicking one re-renders both, _without key isolation_:

import { Suspense } from 'react'
import { DemoSkeleton, KeyIsolationStyles, WithKeyIsolationDemo, WithoutKeyIsolationDemo } from './nuqs-2.5-key-isolation.client'

<KeyIsolationStyles/>

<Suspense fallback={<DemoSkeleton/>}>
  <WithoutKeyIsolationDemo />
</Suspense>

And this is what happens **with key isolation**:

<Suspense fallback={<DemoSkeleton/>}>
  <WithKeyIsolationDemo />
</Suspense>

Key isolation is now built-in for the following adapters:
- React SPA
- React Router (v6 & v7)
- Remix
- TanStack Router

<Callout title="No Next.js? 😢">
 Unfortunately, Next.js uses a single Context to carry a `URLSearchParams{:ts}` object, which changes
 reference whenever any search params change, and therefore re-renders every `useSearchParams{:ts}`
 call site.

 I'm working with the Next.js team to find solutions to this issue to improve performance for
 everyone (not just nuqs users).
</Callout>

## TanStack Router

We've added experimental support for TanStack Router, so you can load and use nuqs-enabled components
from NPM, or shared between different frameworks in a monorepo.

TanStack Router already has great APIs for type-safe URL state management, and we **encourage you to
use those in your application code**. This adapter serves mainly as a compatibility layer.

This also includes _limited_ support for connecting nuqs search params definitions to TSR's type-safe routing,
via the Standard Schema interface.

Refer to the [complete documentation](/docs/adapters#tanstack-router) for what is supported.

## Other changes

### Global defaults for options

You can now specify different defaults for some [options](/docs/options), at the adapter level:

```tsx
// [!code word:defaultOptions]
<NuqsAdapter
  defaultOptions={{
    shallow: false,                 // Always send network requests on updates
    scroll: true,                   // Always scroll to the top of the page on updates
    clearOnDefault: false,          // Keep default values in the URL
    limitUrlUpdates: throttle(250), // Increase global throttle
  }}
>
  {children}
</NuqsAdapter>
```

### Preview support for Next.js 15.5 typed routes

Type-safe routing is now available as an option in Next.js 15.5.

While I'm still working on designing an API to support this elegantly,
a little change to the serializer types can allow you to experiment with
it in userland, using a copy-pastable utility function:

```ts title="src/typed-links.ts"
// Copy this in your codebase
import { Route } from 'next'
import {
  createSerializer,
  type CreateSerializerOptions,
  type ParserMap
} from 'nuqs/server'

export function createTypedLink<Parsers extends ParserMap>(
  route: Route,
  parsers: Parsers,
  options: CreateSerializerOptions<Parsers> = {}
) {
  const serialize = createSerializer<Parsers, Route, Route>(parsers, options)
  return serialize.bind(null, route)
}
```

Usage:

```tsx
import { createTypedLink } from '@/src/typed-links'
import { parseAsFloat, parseAsIsoDate, parseAsString, type UrlKeys } from 'nuqs'

// Reuse your search params definitions objects & urlKeys:
const searchParams = {
  latitude: parseAsFloat.withDefault(0),
  longitude: parseAsFloat.withDefault(0),
}
const urlKeys: UrlKeys<typeof searchParams> = {
  // Define shorthands in the URL
  latitude: 'lat',
  longitude: 'lng'
}

// This is a function bound to /map, with those search params & mapping:
// [!code word:getMapLink]
const getMapLink = createTypedLink('/map', searchParams, { urlKeys })

function MapLinks() {
  return (
    <Link
      href={
        getMapLink({ latitude: 48.86, longitude: 2.35 })
        // → /map?lat=48.86&lng=2.35
      }
    >
      Paris, France
    </Link>
  )
}
```

This is based on the same technique I used on React Router's type-safe `href`
utility in this video:

<iframe
  src="https://www.youtube-nocookie.com/embed/vmONxheVFxQ"
  title="YouTube video player"
  frameBorder="0"
  allow="autoplay; encrypted-media; picture-in-picture; web-share"
  referrerPolicy="strict-origin-when-cross-origin"
  allowFullScreen
  className='aspect-video w-full max-w-2xl mx-auto'
/>

I'll open an RFC discussion soon to define the API, with the goals in mind that:
- It should support both Next.js & React Router typed routes <small>_(if we could connect to TSR too that'd be nice 👀)_</small>
- It should handle static, dynamic & catch-all routes, with type-safe pathname params, search params, and hash.

### Dependencies & bundle size

nuqs is now a **zero runtime dependencies** library! 🙌

While this release packed a lot of new features, we kept it
under **5.5kB** (minified + gzipped).

## Full changelog

### Features

import {PullRequestLine} from '@/src/components/ui/pr-line'

<ul className="not-prose list-none space-y-1.5">
  <PullRequestLine number="855"/>
  <PullRequestLine number="900"/>
  <PullRequestLine number="953"/>
  <PullRequestLine number="965"/>
  <PullRequestLine number="1038"/>
  <PullRequestLine number="1062"/>
  <PullRequestLine number="1066"/>
  <PullRequestLine number="1079"/>
  <PullRequestLine number="1083"/>
</ul>

### Bug fixes

<ul className="not-prose list-none space-y-1.5">
  <PullRequestLine number="996"><wbr/><small className='text-gray-500'>(helps with ESM/CJS interop)</small></PullRequestLine>
  <PullRequestLine number="1057" />
  <PullRequestLine number="1063" />
  <PullRequestLine number="1073" />
</ul>

### Documentation

<ul className="not-prose list-none space-y-1.5">
  <PullRequestLine number="787">→ <a href="/docs/community-adapters/inertia" className="text-sm underline font-medium">Read the docs</a></PullRequestLine>
  <PullRequestLine number="976" />
  <PullRequestLine number="1000" />
  <PullRequestLine number="1004" />
  <PullRequestLine number="1005" />
  <PullRequestLine number="1017" />
  <PullRequestLine number="1021" />
  <PullRequestLine number="1025" />
  <PullRequestLine number="1027" />
  <PullRequestLine number="1032" />
  <PullRequestLine number="1037" />
  <PullRequestLine number="1041" />
  <PullRequestLine number="1043" />
  <PullRequestLine number="1046" />
  <PullRequestLine number="1051" />
  <PullRequestLine number="1052" />
  <PullRequestLine number="1056" />
  <PullRequestLine number="1058" />
  <PullRequestLine number="1070" />
  <PullRequestLine number="1082" /> {/* so meta */}
</ul>

### Other changes

<ul className="not-prose list-none space-y-1.5">
  <PullRequestLine number="985" />
  <PullRequestLine number="990" />
  <PullRequestLine number="1011" />
  <PullRequestLine number="1029" />
  <PullRequestLine number="1033" />
  <PullRequestLine number="1065" />
  <PullRequestLine number="1067" />
  <PullRequestLine number="1074" />
  <PullRequestLine number="1077" />
  <PullRequestLine number="1078" />
  <PullRequestLine number="1080" />
  <PullRequestLine number="1081" />
  <PullRequestLine number="1086"><small className='text-gray-500 italic'>Congrats on your first OSS contribution! 🙌</small></PullRequestLine>
</ul>

{/* Raw data in case the PullRequestLine component becomes too expensive */}
{/*
### Features

- [#855](https://github.com/47ng/nuqs/pull/855): Key isolation, by [@franky47](https://github.com/franky47)
- [#900](https://github.com/47ng/nuqs/pull/900): Debounce, by [@franky47](https://github.com/franky47)
- [#953](https://github.com/47ng/nuqs/pull/953): Add support for TanStack Router, by [@ahmedrowaihi](https://github.com/ahmedrowaihi)
- [#965](https://github.com/47ng/nuqs/pull/965): Add Standard Schema interface, by [@franky47](https://github.com/franky47)
- [#1038](https://github.com/47ng/nuqs/pull/1038): Add const modifier to literal parsers to auto-infer their arguments as literals, by [@neefrehman](https://github.com/neefrehman)
- [#1062](https://github.com/47ng/nuqs/pull/1062): Export ./package.json in exports field for Module Federation support, by [@AfeefRazick](https://github.com/AfeefRazick)
- [#1066](https://github.com/47ng/nuqs/pull/1066): defaultOptions for NuqsAdapter, by [@TkDodo](https://github.com/TkDodo)
- [#1079](https://github.com/47ng/nuqs/pull/1079): Add support for more global default options at the adapter level, by [@franky47](https://github.com/franky47)
- [#1083](https://github.com/47ng/nuqs/pull/1083): Allow specifying a different base type for the serializer, by [@franky47](https://github.com/franky47)

### Bug fixes

- [#996](https://github.com/47ng/nuqs/pull/996): Replace require by default conditional export field, by [@stefan-schubert-sbb](https://github.com/stefan-schubert-sbb)
- [#1057](https://github.com/47ng/nuqs/pull/1057): Type inference for defaultValue of object syntax, by [@TkDodo](https://github.com/TkDodo)
- [#1063](https://github.com/47ng/nuqs/pull/1063): Remove esm-only on TanStack Router export, by [@franky47](https://github.com/franky47)
- [#1073](https://github.com/47ng/nuqs/pull/1073): Handle JSON in TanStack Router, by [@franky47](https://github.com/franky47)

### Documentation

- [#787](https://github.com/47ng/nuqs/pull/787): Add Inertia community adapter, by [@Joehoel](https://github.com/Joehoel)
- [#976](https://github.com/47ng/nuqs/pull/976): Add blog section, by [@franky47](https://github.com/franky47)
- [#1000](https://github.com/47ng/nuqs/pull/1000): Vercel OSS program, by [@franky47](https://github.com/franky47)
- [#1004](https://github.com/47ng/nuqs/pull/1004): Add code.store & oxom as sponsors 💖, by [@franky47](https://github.com/franky47)
- [#1005](https://github.com/47ng/nuqs/pull/1005): The URL type-safety iceberg, by [@franky47](https://github.com/franky47)
- [#1017](https://github.com/47ng/nuqs/pull/1017): Fix non-null assertions, by [@franky47](https://github.com/franky47)
- [#1021](https://github.com/47ng/nuqs/pull/1021): Add Deploy on Vercel button, by [@franky47](https://github.com/franky47)
- [#1025](https://github.com/47ng/nuqs/pull/1025): Extend next-app example to include more features, by [@I-3B](https://github.com/I-3B)
- [#1027](https://github.com/47ng/nuqs/pull/1027): Fix mobile navbar collapse & sticky, by [@franky47](https://github.com/franky47)
- [#1032](https://github.com/47ng/nuqs/pull/1032): Fix 500 error on Vercel ISR, by [@franky47](https://github.com/franky47)
- [#1037](https://github.com/47ng/nuqs/pull/1037): Add Aurora Scharff as a sponsor 💖, by [@franky47](https://github.com/franky47)
- [#1041](https://github.com/47ng/nuqs/pull/1041): Fix transition docs to not call parser as function, by [@phelma](https://github.com/phelma)
- [#1043](https://github.com/47ng/nuqs/pull/1043): Title is hidden behind headers on mobile, by [@awosky](https://github.com/awosky)
- [#1046](https://github.com/47ng/nuqs/pull/1046): Update NUQS-404.md, by [@dmytro-palaniichuk](https://github.com/dmytro-palaniichuk)
- [#1051](https://github.com/47ng/nuqs/pull/1051): Add effect schema parser page, by [@ethanniser](https://github.com/ethanniser)
- [#1052](https://github.com/47ng/nuqs/pull/1052): Debounce docs edits, by [@franky47](https://github.com/franky47)
- [#1056](https://github.com/47ng/nuqs/pull/1056): Migrate docs to Fumadocs 15, Tailwind CSS v4, by [@fuma-nama](https://github.com/fuma-nama)
- [#1058](https://github.com/47ng/nuqs/pull/1058): Fix default value for shallow in React Router disclaimer, by [@franky47](https://github.com/franky47)
- [#1070](https://github.com/47ng/nuqs/pull/1070): Prevent NaN appearing in pagination example, by [@87xie](https://github.com/87xie)
- [#1082](https://github.com/47ng/nuqs/pull/1082): Add nuqs 2.5 release blog post, by [@franky47](https://github.com/franky47)

### Other changes
- [#985](https://github.com/47ng/nuqs/pull/985): Use React Compiler RC, by [@franky47](https://github.com/franky47)
- [#990](https://github.com/47ng/nuqs/pull/990): Replace tsup with tsdown, by [@franky47](https://github.com/franky47)
- [#1011](https://github.com/47ng/nuqs/pull/1011): Add RSS feed auto-discovery, by [@franky47](https://github.com/franky47)
- [#1029](https://github.com/47ng/nuqs/pull/1029): Fix API stability test, by [@franky47](https://github.com/franky47)
- [#1033](https://github.com/47ng/nuqs/pull/1033): Linting PR titles, by [@franky47](https://github.com/franky47)
- [#1065](https://github.com/47ng/nuqs/pull/1065): Add TanStack Router to og:images, by [@franky47](https://github.com/franky47)
- [#1067](https://github.com/47ng/nuqs/pull/1067): Improve stats page, by [@franky47](https://github.com/franky47)
- [#1074](https://github.com/47ng/nuqs/pull/1074): Configure MDX types, by [@remcohaszing](https://github.com/remcohaszing)
- [#1077](https://github.com/47ng/nuqs/pull/1077): Track beta versions adoption in the stats page, by [@franky47](https://github.com/franky47)
- [#1078](https://github.com/47ng/nuqs/pull/1078): Update dependencies, by [@franky47](https://github.com/franky47)
- [#1080](https://github.com/47ng/nuqs/pull/1080): Pass children as config in createElement to avoid ts-expect-error, by [@franky47](https://github.com/franky47)
- [#1081](https://github.com/47ng/nuqs/pull/1081): Reduce the bundle size, by [@franky47](https://github.com/franky47)
- [#1086](https://github.com/47ng/nuqs/pull/1086): Add publint step to CI workflow, by [@Amirmohammad-Bashiri](https://github.com/Amirmohammad-Bashiri)
*/}

<hr />

## What's next?

Long standing issues and feature requests include:

- Support for **native arrays** by repeating keys in the URL (eg: `?foo=bar&foo=egg` gives you `['bar', 'egg']{:ts}`)
- **Runtime validation** with Standard Schema (Zod, Valibot, ArkType etc), to validate what TypeScript can't represent (like number ranges & string formats).
- Support for **typed links** in Next.js 15.5 and React Router's `href` utility.

## Thanks

I want to thank [sponsors](https://github.com/sponsors/franky47),
[contributors](https://github.com/47ng/nuqs/graphs/contributors)
and people who raised issues, discussions and reviewed PRs on
[GitHub](https://github.com/47ng/nuqs), [Bluesky](https://bsky.app/profile/nuqs.dev) and [X/Twitter](https://x.com/nuqs47ng).
You are the growing community that drives this project forward,
and I couldn't be happier with the response.

### Sponsors

import { InlineSponsorsList } from '@/src/app/(pages)/_landing/sponsors'
import { VercelOssBadge } from '@/src/components/vercel-oss-badge'

<a href="https://vercel.com/blog/spring25-oss-program">
  <VercelOssBadge className='mt-8'/>
</a>

<InlineSponsorsList className="not-prose my-8" />

Thanks to these amazing people and companies, I'm able to dedicate more time to this project and make it better for everyone.
Join them on [💖 GitHub Sponsors](https://github.com/sponsors/franky47)!

### Contributors

Huge thanks to [@87xie](https://github.com/87xie), [@AfeefRazick](https://github.com/AfeefRazick), [@ahmedrowaihi](https://github.com/ahmedrowaihi), [@Amirmohammad-Bashiri](https://github.com/Amirmohammad-Bashiri), [@AmruthPillai](https://github.com/AmruthPillai), [@an-h2](https://github.com/an-h2), [@anhskohbo](https://github.com/anhskohbo), [@awosky](https://github.com/awosky), [@brandanking-decently](https://github.com/brandanking-decently), [@devhasson](https://github.com/devhasson), [@didemkkaslan](https://github.com/didemkkaslan), [@dinogit](https://github.com/dinogit), [@dmytro-palaniichuk](https://github.com/dmytro-palaniichuk), [@Elya29](https://github.com/Elya29), [@ericwang401](https://github.com/ericwang401), [@ethanniser](https://github.com/ethanniser), [@fuma-nama](https://github.com/fuma-nama), [@gensmusic](https://github.com/gensmusic), [@I-3B](https://github.com/I-3B), [@jaberamin9](https://github.com/jaberamin9), [@Joehoel](https://github.com/Joehoel), [@Kavan72](https://github.com/Kavan72), [@krisnaw](https://github.com/krisnaw), [@Manjit2003](https://github.com/Manjit2003), [@neefrehman](https://github.com/neefrehman), [@phelma](https://github.com/phelma), [@remcohaszing](https://github.com/remcohaszing), [@SeanCassiere](https://github.com/SeanCassiere), [@snelsi](https://github.com/snelsi), [@stefan-schubert-sbb](https://github.com/stefan-schubert-sbb), [@thewebartisan7](https://github.com/thewebartisan7), [@TkDodo](https://github.com/TkDodo), [@vanquishkuso](https://github.com/vanquishkuso), and [@Willem-Jaap](https://github.com/Willem-Jaap) for helping!


================================================
FILE: packages/docs/content/blog/nuqs-2.mdx
================================================
---
title: nuqs 2
description: Opening up to other React frameworks
author: François Best
date: 2024-10-22
---

nuqs@2.0.0 is available, try it now:

```npm
npm install nuqs@latest
```

It's packing exciting features & improvements, including:

- [Support for other React frameworks](#hello-react): Next.js, React SPA, Remix, React Router, and more to come
- A built-in [testing adapter](#testing) to unit-test your components in isolation
- [Bundle size improvements](#bundle-size-improvements)
- Interactive documentation, with [community parsers](/docs/parsers/community)

<hr />

## Hello, React! 👋 ⚛️ [#hello-react]

nuqs started as a Next.js-only hook, and v2 brings compatibility for other React frameworks:

- Next.js 14 & 15 (app & pages routers)
- React SPA
- Remix
- React Router

No code change is necessary in components that use nuqs hooks,
making them **universal** across all supported frameworks.

The only new requirement is to wrap your React tree with an
[adapter](/docs/adapters) for your framework.

Example for a React SPA with Vite:

```tsx title="src/main.tsx"
// [!code word:NuqsAdapter]
import { NuqsAdapter } from 'nuqs/adapters/react'

createRoot(document.getElementById('root')!).render(
  <NuqsAdapter>
    <App />
  </NuqsAdapter>
)
```

<Callout>
  The [adapters documentation](/docs/adapters) has examples for all supported
  frameworks.
</Callout>

## Testing

One of the major pain points with nuqs v1 was testing components that used its hooks.

Nuqs v2 comes with a built-in [testing adapter](/docs/testing) that mocks URL behaviours,
allowing you to test your components in isolation, outside of any framework runtime.

You can use it with any unit testing framework that renders React components
(I recommend [Vitest](https://vitest.dev) & [Testing Library](https://testing-library.com/)).

```tsx title="counter-button.test.tsx"
// [!code word:NuqsTestingAdapter]
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(<CounterButton />, {
    // 1. Setup the test by passing initial search params / querystring:
    wrapper: ({ children }) => (
      <NuqsTestingAdapter searchParams="?count=42" onUrlUpdate={onUrlUpdate}>
        {children}
      </NuqsTestingAdapter>
    )
  })
  // 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')
})
```

The adapter conforms to the **setup** / **act** / **assert** testing strategy, allowing you
to:

1. Set the initial URL search params
2. Let your test framework perform actions on your component
3. Asserting on how the URL was changed as a result

## Breaking changes & migration

The biggest breaking change is the introduction of [adapters](/docs/adapters).
Another one is related to deprecated APIs.

The `next-usequerystate` package that started this journey is no longer updated.
All updates are now published under the `nuqs` package name.

The minimum version of Next.js supported is now 14.2.0. It is compatible with
Next.js 15, including the async `searchParams{:ts}` page prop in the [server-side cache](/docs/server-side).

There are some important behaviour changes, based on feedback from the community:

- [`clearOnDefault{:ts}`](/docs/options#clear-on-default) is now `true{:ts}` by default
- [`startTransition{:ts}`](/docs/options#transitions) no longer sets `shallow: false{:ts}`
- [`parseAsJson{:ts}`](/docs/parsers/built-in#json) now requires a validation function

<Callout>
  Read the complete [migration guide](/docs/migrations/v2) to update your
  applications.
</Callout>

## Bundle size improvements

By moving to **ESM-only**, and dropping hacks needed to support older versions of Next.js,
the bundle size is now **20% smaller** than v1. It's also **side-effects free** and **tree-shakable**.

## What's next?

The community and I have a lot of ideas for the future of nuqs, including:

- A unified, scalable, type-safe routing experience in all supported React frameworks
- Community-contributed parsers & adapters
- New options: debouncing, global defaults override
- Middleware to migrate old URLs to new ones
- Better Zod integration for type-safe & runtime-safe validation

## Thanks

I want to thank [sponsors](https://github.com/sponsors/franky47),
[contributors](https://github.com/47ng/nuqs/graphs/contributors)
and people who raised issues and discussions on
[GitHub](https://github.com/47ng/nuqs) and [X/Twitter](https://x.com/nuqs47ng).
You are the growing community that drives this project forward,
and I couldn't be happier with the response.

### Sponsors

- [Pontus Abrahamsson](https://x.com/pontusab), founder of [Midday.ai](https://midday.ai)
- [Carl Lindesvard](https://x.com/CarlLindesvard), founder of [OpenPanel](https://openpanel.dev)
- [Robin Wieruch](https://x.com/rwieruch), author of [The Road to Next](https://www.road-to-next.com/)
- [Yoann Fleury](https://x.com/YoannFleuryDev)
- [Sunghyun Cho](https://github.com/anaclumos)
- [Jalol](https://github.com/mirislomovmirjalol)

Thanks to these amazing people, I'm able to dedicate more time to this project and make it better for everyone.
Join them on [GitHub Sponsors](https://github.com/sponsors/franky47)!

### Contributors

Huge thanks to [@andreisocaciu](https://github.com/andreisocaciu), [@tordans](https://github.com/tordans), [@prasannamestha](https://github.com/prasannamestha), @Talent30, [@neefrehman](https://github.com/neefrehman), [@chbg](https://github.com/chbg), [@dopry](https://github.com/dopry), [@weisisheng](https://github.com/weisisheng), [@hugotiger](https://github.com/hugotiger), [@iuriizaporozhets](https://github.com/iuriizaporozhets), [@rikbrown](https://github.com/rikbrown), [@mateogianolio](https://github.com/mateogianolio), [@timheerwagen](https://github.com/timheerwagen), [@psdmsft](https://github.com/psdmsft), and [@psdewar](https://github.com/psdewar) for helping!


================================================
FILE: packages/docs/content/blog/open-source-pledge-recipient.tsx
================================================
type OpenSourcePledgeRecipientProps = {
  handle: string
  name: string
}

export function OpenSourcePledgeRecipient({
  handle,
  name
}: OpenSourcePledgeRecipientProps) {
  return (
    <span>
      <img
        src={`https://github.com/${handle}.png`}
        alt={`${name}'s avatar`}
        role="presentation"
        width="16px"
        height="16px"
        className="not-prose my-1.5 mr-2 inline size-6 rounded-full align-middle"
      />
      <a href={`https://github.com/sponsors/${handle}`}>{name}</a>
    </span>
  )
}


================================================
FILE: packages/docs/content/blog/open-source-pledge.mdx
================================================
---
title: Signing the Open Source Pledge
description: Giving back to maintainers of the OSS projects nuqs depends on.
author: François Best
date: 2025-11-27
---

Today is Thanksgiving, and one thing I'm thankful for is this **open-source community** I'm lucky to be a part of.

Around the world and online, I have met folks who build cool things on the web,
whether OSS SaaS products or foundational libraries and building blocks for all to use and build on top of.
This open sharing of knowledge, code, and tools is one of the reasons why I left the music industry
8 years ago and settled on the Web as my building platform of choice.

At the beginning of 2025, I had two goals:
1. Speak at a conference _(done, three times 🇫🇷🇺🇸🇬🇧)_
2. Sign the Open Source Pledge

<a href="https://opensourcepledge.com" className="p-8 max-w-xl mx-auto invert hue-rotate-180 dark:hue-rotate-0 dark:invert-0 block">
![Open Source Pledge logo](./opensourcepledge.png)
</a>

This year has been a wild ride, but the combination of being backed by
[GitHub sponsors](https://github.com/sponsors/franky47) (thank you! 💖)
and the recent winning of the Clerk Hackathon allows me to sign the
[Open Source Pledge](https://opensourcepledge.com) on behalf of nuqs for the first time this year.

I'm giving a total of **2700€** (USD $3,132) divided equally between the
maintainers of dependencies that help me build nuqs, and/or that I use in my client projects:

import { OpenSourcePledgeRecipient as OSSPR } from './open-source-pledge-recipient'

<ul className="list-none pl-0 ml-0">
  <li><OSSPR name="Andrey Sitnik" handle="ai" /> for [`size-limit`](https://npmjs.org/package/size-limit), to keep the bundle size small.</li>
  <li><OSSPR name="Anthony Fu" handle="antfu" />'s [collective](https://opencollective.com/antfu) for [`vitest`](https://vitest.dev), to make sure everything works fine.</li>
  <li><OSSPR name="Artem Zakharchenko" handle="kettanaito" /> for [`msw`](https://mswjs.io), the best network mocking library ever made.</li>
  <li><OSSPR name="Bjorn Lu" handle="bluwy" /> for [`publint`](https://publint.dev), to make sure I follow best practices.</li>
  <li><OSSPR name="Daishi Kato" handle="dai-shi" /> for [`jotai`](https://jotai.org), the gateway drug to signals for React devs.</li>
  <li><OSSPR name="Dominik Dorfmeister" handle="TkDodo" /> for [`@tanstack/react-query`](https://tanstack.com/query) & contributing to nuqs.</li>
  <li><OSSPR name="fregante" handle="fregante" /> for [Refined GitHub](https://github.com/refined-github/refined-github), so useful I can't use the stock UI anymore.</li>
  <li><OSSPR name="Fuma Nama" handle="fuma-nama" /> for [`fumadocs`](https://fumadocs.dev), which makes these interactive docs possible.</li>
  <li><OSSPR name="Kevin Deng" handle="sxzz" /> for [`tsdown`](https://tsdown.dev), the only bundler that ticked all the boxes.</li>
  <li><OSSPR name="Lars Kappert" handle="webpro" /> for [`knip`](https://knip.dev), to find unused code and ✂️ knip it off.</li>
  <li><OSSPR name="Matt Travi" handle="travi" /> for [`semantic-release`](https://semantic-release.gitbook.io/semantic-release), that lets me never think about version numbers again.</li>
  <li><OSSPR name="Mohammad Bagher" handle="Aslemammad" /> for [`pkg.pr.new`](https://pkg.pr.new), the maintainer's superpower: preview builds on PRs.</li>
  <li><OSSPR name="Nicolas Dubien" handle="dubzzz" /> for [`fast-check`](https://fast-check.dev), which fuzzy-tests URL encoding.</li>
  <li><OSSPR name="SaltyAom" handle="SaltyAom" /> for [`elysia`](https://elysiajs.com), a cool type-safe API framework I want to play more with.</li>
  <li><OSSPR name="Tom Lienard" handle="QuiiBz" /> for [`sherif`](https://npmjs.org/package/sherif) which enforces the Law in the nuqs monorepo.</li>
  <li><OSSPR name="Fastify" handle="fastify" />, that I use daily for client work as a backend framework.</li>
  <li><OSSPR name="Node.js" handle="nodejs" />, the heart of our FLOSS, community-driven ecosystem.</li>
  <li><OSSPR name="PNPM" handle="pnpm" />, my package manager of choice that links it all together.</li>
</ul>

<br/>

To that list, we can add the following other OSS sponsorship payments I made during the year:

<ul className="list-none pl-0 ml-0">
  <li><OSSPR name="Alem Tuzlak" handle="alemtuzlak" />: $10</li>
  <li><OSSPR name="Dai" handle="dai" />: $174 <small>(I messed up `@dai-shi`'s sponsorship with the bulk CSV import, and so `@dai` got a lucky sponsorship 🙌)</small></li>
</ul>

<Callout title="Open Source Pledge summary for 2025" id="total">
  In total, this amounts to <strong>$3,316</strong> paid on behalf of the nuqs project (with myself as the sole "employee") to OSS maintainers.
</Callout>

Thank you to all of those wonderful folks and organisations, and happy Thanksgiving. 🫶

================================================
FILE: packages/docs/content/docs/about.mdx
================================================
---
title: About
description: About the nuqs library
---

## License

Released under the [MIT License](https://github.com/47ng/nuqs/blob/next/LICENSE), made with ❤️ by [François Best](https://francoisbest.com).

Using this package at work ? [Sponsor me](https://github.com/sponsors/franky47)
to help with support and maintenance.

## Contributors

<img
  alt="Project analytics and stats"
  src="https://repobeats.axiom.co/api/embed/3ee740e4729dce3992bfa8c74645cfebad8ba034.svg"
/>


## About the name

### How is it pronounced?

Up to you. I say "nucks" (like ducks 🦆🦆).


### What does nuqs mean?

> **Never underestimate query strings**.

Kidding aside, it's the initials of the original name package name, `Next-UseQueryState`,
which was too long and annoying to type.

I realised after the fact that the word `nuqs` in Urdu & Arabic means "flaw" or "defect".
It's a good reminder that:

> Perfection is a direction, not a destination.
>
> <figcaption>-- [James Wright](https://www.youtube.com/shorts/CH_d9lVRLWk)</figcaption>

I probably should have checked the meaning of the word before using it,
and apologise to any Urdu/Arabic-speaking user who might find it offensive.

It's also Klingon for "What?!", the kind of reaction you get when you
move from `useState{:ts}` to URL state for the first time. 🖖



================================================
FILE: packages/docs/content/docs/adapters.mdx
================================================
---
title: Adapters
description: Using nuqs in your React framework of choice
---

import {
  NextJS,
  ReactRouter,
  ReactRouterV7,
  ReactSPA,
  Remix,
  TanStackRouter,
  Vitest,
} from '@/src/components/frameworks'

Since version 2, you can now use nuqs in the following React frameworks, by
wrapping it with a `NuqsAdapter{:ts}` context provider:

- <NextJS className='inline mr-1.5' role="presentation"/> [Next.js (app router)](#nextjs-app-router)
- <NextJS className='inline mr-1.5' role="presentation"/> [Next.js (pages router)](#nextjs-pages-router)
- <ReactSPA className='inline mr-1.5' role="presentation" /> [React SPA (eg: with Vite)](#react-spa)
- <Remix className='inline mr-1.5' role="presentation" /> [Remix](#remix)
- <ReactRouter className='inline mr-1.5' role="presentation" /> [React Router v6](#react-router-v6)
- <ReactRouterV7 className='inline mr-1.5' role="presentation" /> [React Router v7](#react-router-v7)
- <TanStackRouter className='inline mr-1.5 not-prose' role="presentation"/> [TanStack Router](#tanstack-router)

## <NextJS className='inline mr-1.5 -mt-1' role="presentation" /> Next.js [#nextjs]

### App router [#nextjs-app-router]

Wrap your `{children}{:ts}` with the `NuqsAdapter{:ts}` component in your root layout file:

```tsx title="src/app/layout.tsx"
// [!code word:NuqsAdapter]
import { NuqsAdapter } from 'nuqs/adapters/next/app'
import { type ReactNode } from 'react'

export default function RootLayout({
  children
}: {
  children: ReactNode
}) {
  return (
    <html>
      <body>
        <NuqsAdapter>{children}</NuqsAdapter>
      </body>
    </html>
  )
}
```

### Pages router [#nextjs-pages-router]

Wrap the `<Component>{:ts}` page outlet with the `NuqsAdapter{:ts}` component in your `_app.tsx` file:

```tsx title="src/pages/_app.tsx"
// [!code word:NuqsAdapter]
import type { AppProps } from 'next/app'
import { NuqsAdapter } from 'nuqs/adapters/next/pages'

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <NuqsAdapter>
      <Component {...pageProps} />
    </NuqsAdapter>
  )
}
```

### Unified (router-agnostic) [#nextjs-unified]

If your Next.js app uses **both the app and pages routers** and the adapter needs
to be mounted in either, you can import the unified adapter, at the cost
of a slightly larger bundle size (~100B).

```tsx
import { NuqsAdapter } from 'nuqs/adapters/next'
```

<br/>

The main reason for adapters is to open up nuqs to other React frameworks:

## <ReactSPA className='inline mr-1.5 -mt-1' role="presentation"/> React SPA [#react-spa]

Example, with Vite:

```tsx title="src/main.tsx"
// [!code word:NuqsAdapter]
import { NuqsAdapter } from 'nuqs/adapters/react'

createRoot(document.getElementById('root')!).render(
  <NuqsAdapter>
    <App />
  </NuqsAdapter>
)
```

<Callout title="Note">
Because there is no known server in this configuration, the
[`shallow: false{:ts}`](/docs/options#shallow) option will have no effect.

See below for some options:
</Callout>

### Full page navigation on <br className='hidden [#nd-toc_&]:block'/>`shallow: false{:ts}` [#full-page-navigation-on-shallow-false]

<FeatureSupportMatrix introducedInVersion='2.4.0' support={{
  supported: true,
  frameworks: ['React SPA']
}}/>

You can specify a flag to perform a full-page navigation when
updating query state configured with `shallow: false{:ts}`, to notify the web server
that the URL state has changed, if it needs it for server-side rendering other
parts of the application than the static React bundle:

```tsx title="src/main.tsx"
// [!code word:fullPageNavigationOnShallowFalseUpdates]
createRoot(document.getElementById('root')!).render(
  <NuqsAdapter fullPageNavigationOnShallowFalseUpdates>
    <App />
  </NuqsAdapter>
)
```

This may be useful for servers not written in JavaScript, like Django (Python),
Rails (Ruby), Laravel (PHP), Phoenix (Elixir) etc...

## <Remix className='inline mr-1.5 -mt-1' role="presentation"/> Remix [#remix]

```tsx title="app/root.tsx"
// [!code word:NuqsAdapter]
import { NuqsAdapter } from 'nuqs/adapters/remix'

// ...

export default function App() {
  return (
    <NuqsAdapter>
      <Outlet />
    </NuqsAdapter>
  )
}
```

## <ReactRouter className='inline mr-1.5 -mt-1' role="presentation"/> React Router v6 [#react-router-v6]

```tsx title="src/main.tsx"
// [!code word:NuqsAdapter]
import { NuqsAdapter } from 'nuqs/adapters/react-router/v6'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import App from './App'

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />
  }
])

export function ReactRouter() {
  return (
    <NuqsAdapter>
      <RouterProvider router={router} />
    </NuqsAdapter>
  )
}
```

<Callout>

 Only `BrowserRouter` is supported. There may be support for `HashRouter`
 in the future (see issue [#810](https://github.com/47ng/nuqs/issues/810)), but
 support for `MemoryRouter` is not planned.

</Callout>

## <ReactRouterV7 className='inline mr-1.5 -mt-1' role="presentation"/> React Router v7 [#react-router-v7]

```tsx title="app/root.tsx"
// [!code word:NuqsAdapter]
import { NuqsAdapter } from 'nuqs/adapters/react-router/v7'
import { Outlet } from 'react-router'

// ...

export default function App() {
  return (
    <NuqsAdapter>
      <Outlet />
    </NuqsAdapter>
  )
}
```

<Callout type="warn" title="Deprecation notice">
  The generic import `nuqs/adapters/react-router` (pointing to v6)
  is deprecated and will be removed in nuqs@3.0.0.

  Please pin your imports to the specific version,
  eg: `nuqs/adapters/react-router/v6` or `nuqs/adapters/react-router/v7`.

  The main difference is where the React Router hooks are imported from:
  `react-router-dom` for v6, and `react-router` for v7.
</Callout>

## <TanStackRouter className='inline mr-1.5 -mt-1 not-prose' role="presentation"/> TanStack Router [#tanstack-router]

```tsx title="src/routes/__root.tsx"
// [!code word:NuqsAdapter]
import { NuqsAdapter } from 'nuqs/adapters/tanstack-router'
import { Outlet, createRootRoute } from '@tanstack/react-router'

export const Route = createRootRoute({
  component: () => (
    <>
      <NuqsAdapter>
        <Outlet />
      </NuqsAdapter>
    </>
  ),
})
```

<Callout>

TanStack Router support is experimental and does not yet cover TanStack Start.

</Callout>

### Type-safe routing via `validateSearch`

TanStack Router comes with built-in type-safe search params support,
and its APIs should likely be used in your application code for best DX.

Nevertheless, sometimes you may need to import a component that uses nuqs
(from NPM or a shared library), and benefit from TanStack Router's type-safe routing.

You may do so via the [Standard Schema](/docs/utilities#standard-schema) support:

```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,
  // [!code highlight:3]
  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 (
    <Link
      to="/search"
      search={{
        searchQuery: 'foo',
        // note: we're not specifying pageIndex
      }}
    />
  )
}
```

Note that the `partialOutput{:ts}` flag allows specifying only a subset of
the search params for a given route. It also does not reflect those search
in the URL automatically, following nuqs' behaviour more closely.

<Callout title="Caveats" type="warn">

Due to differences in how TanStack Router and nuqs handle serialisation and deserialisation
(global in TanStack Router and per-key in nuqs), only _trivial_ state types are supported for
type-safe linking. Those include all string-based parsers (string, enum, literals),
number-based (integer, float, number literal), boolean, and JSON.

The `urlKeys` feature to provide shorthand key names is also not supported for similar
reasons.

</Callout>

## <Vitest className='inline mr-1.5 -mt-1' role="presentation"/> Testing

<Callout>
  Documentation for the `NuqsTestingAdapter{:ts}` is on the [testing page](/docs/testing).
</Callout>


================================================
FILE: packages/docs/content/docs/basic-usage.mdx
================================================
---
title: Basic usage
description: Replacing React.useState with useQueryState
---

import {
  DemoFallback,
  BasicUsageDemo
} from '@/content/docs/parsers/demos'

<Callout title="Prerequisite">
  Have you setup your app with the appropriate [**adapter**](/docs/adapters)? Then you
  are all set!
</Callout>

If you are using `React.useState` to manage your local UI state,
you can replace it with `useQueryState` to sync it with the URL.

```tsx
'use client'

import { useQueryState } from 'nuqs'

export function Demo() {
  const [name, setName] = useQueryState('name')
  return (
    <>
      <input value={name || ''} onChange={e => setName(e.target.value)} />
      <button onClick={() => setName(null)}>Clear</button>
      <p>Hello, {name || 'anonymous visitor'}!</p>
    </>
  )
}
```

<Suspense fallback={<DemoFallback/>}>
  <BasicUsageDemo />
</Suspense>

`useQueryState` takes one required argument: the key to use in the query string.

Like `React.useState`, it returns an array with the value present in the query
string as a string (or `null{:ts}` if none was found), and a state updater function.

Example outputs for our demo example:

| URL          | name value   | Notes                                                             |
| ------------ | ------------ | ----------------------------------------------------------------- |
| `/`          | `null{:ts}`  | No `name` key in URL                                              |
| `/?name=`    | `''{:ts}`    | Empty string                                                      |
| `/?name=foo` | `'foo'{:ts}` ||
| `/?name=2`   | `'2'{:ts}`   | Always returns a string by default, see [Parsers](/docs/parsers) |

<Callout title="Tip">
  Setting `null{:ts}` as a value will remove the key from the query string.
</Callout>

## Default values

When the query string is not present in the URL, the default behaviour is to
return `null{:ts}` as state.

It can make state updating and UI rendering tedious.
Take this example of a simple counter stored in the URL:

```tsx
import { useQueryState, parseAsInteger } from 'nuqs'

export default () => {
  const [count, setCount] = useQueryState('count', parseAsInteger)
  return (
    <>
      <pre>count: {count}</pre>
      <button onClick={() => setCount(0)}>Reset</button>
      {/* handling null values in setCount is annoying: */}
      <button onClick={() => setCount(c => (c ?? 0) + 1)}>+</button>
      <button onClick={() => setCount(c => (c ?? 0) - 1)}>-</button>
      <button onClick={() => setCount(null)}>Clear</button>
    </>
  )
}
```

You can provide a default value as the second argument to `useQueryState` (or
via the `.withDefault{:ts}` builder method on parsers):

```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
```

It makes it much easier to handle state updates:

```tsx
const increment = () => setCount(c => c + 1) // c will never be null
const decrement = () => setCount(c => c - 1) // c will never be null
const clearCount = () => setCount(null) // Remove query from the URL
```

<Callout title="Note">
  The default value is internal to React, it will **not** be written to the
  URL _unless you set it explicitly_ and use the [`clearOnDefault: false{:ts}` option](/docs/options#clear-on-default).
</Callout>

<Callout title="Tip">
  The default value is also returned if the value is _invalid_ for the parser.
</Callout>

<Callout title="Tip">
  Setting the state to `null{:ts}` when a default value is specified:
  1. Clears the query from the URL
  2. Returns the default value as state
</Callout>


================================================
FILE: packages
Download .txt
gitextract_4cpkr29x/

├── .agents/
│   └── docs/
│       ├── adapter-development.md
│       ├── api-design.md
│       ├── git-workflow.md
│       ├── parser-implementation.md
│       ├── quality-standards.md
│       └── testing.md
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── config.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── analyse-nextjs-release.yml
│       ├── ci-cd.yml
│       ├── clear-shipping-next.yml
│       ├── milestone-automation.yml
│       ├── pkg.pr.new.yml
│       ├── pr-base-enforcement.yml
│       ├── pr-lint.yml
│       └── test-against-nextjs-release.yml
├── .gitignore
├── .husky/
│   └── commit-msg
├── .node-version
├── .vscode/
│   └── settings.json
├── AGENTS.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── errors/
│   ├── NUQS-101.md
│   ├── NUQS-303.md
│   ├── NUQS-404.md
│   ├── NUQS-409.md
│   ├── NUQS-414.md
│   ├── NUQS-422.md
│   ├── NUQS-429.md
│   ├── NUQS-500.md
│   └── NUQS-501.md
├── package.json
├── packages/
│   ├── docs/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── components.json
│   │   ├── content/
│   │   │   ├── blog/
│   │   │   │   ├── 2025.mdx
│   │   │   │   ├── beware-the-url-type-safety-iceberg.components.tsx
│   │   │   │   ├── beware-the-url-type-safety-iceberg.mdx
│   │   │   │   ├── nuqs-2.5-key-isolation.client.tsx
│   │   │   │   ├── nuqs-2.5.mdx
│   │   │   │   ├── nuqs-2.mdx
│   │   │   │   ├── open-source-pledge-recipient.tsx
│   │   │   │   └── open-source-pledge.mdx
│   │   │   └── docs/
│   │   │       ├── about.mdx
│   │   │       ├── adapters.mdx
│   │   │       ├── basic-usage.mdx
│   │   │       ├── batching.mdx
│   │   │       ├── debugging.mdx
│   │   │       ├── installation.mdx
│   │   │       ├── internal/
│   │   │       │   └── design-system.mdx
│   │   │       ├── limits.mdx
│   │   │       ├── meta.json
│   │   │       ├── migrations/
│   │   │       │   └── v2.mdx
│   │   │       ├── options.client.tsx
│   │   │       ├── options.mdx
│   │   │       ├── parsers/
│   │   │       │   ├── built-in.mdx
│   │   │       │   ├── community/
│   │   │       │   │   ├── effect-schema-demo.tsx
│   │   │       │   │   ├── effect-schema.mdx
│   │   │       │   │   ├── meta.json
│   │   │       │   │   ├── tanstack-table.generator.tsx
│   │   │       │   │   ├── tanstack-table.mdx
│   │   │       │   │   ├── zod-codecs.demo.tsx
│   │   │       │   │   ├── zod-codecs.lib.ts
│   │   │       │   │   ├── zod-codecs.mdx
│   │   │       │   │   ├── zod-codecs.skeleton.tsx
│   │   │       │   │   └── zod-codecs.source.tsx
│   │   │       │   ├── demos.tsx
│   │   │       │   ├── making-your-own.mdx
│   │   │       │   └── meta.json
│   │   │       ├── seo.mdx
│   │   │       ├── server-side.mdx
│   │   │       ├── testing.mdx
│   │   │       ├── tips-tricks.mdx
│   │   │       ├── troubleshooting.mdx
│   │   │       └── utilities.mdx
│   │   ├── mdx-components.tsx
│   │   ├── next.config.mjs
│   │   ├── package.json
│   │   ├── public/
│   │   │   └── .well-known/
│   │   │       └── atproto-did
│   │   ├── rehype-code.config.ts
│   │   ├── sentry.edge.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── source.config.ts
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── (llms)/
│   │   │   │   │   ├── llms/
│   │   │   │   │   │   └── [...slug]/
│   │   │   │   │   │       └── route.tsx
│   │   │   │   │   ├── llms-full.txt/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── llms.txt/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── (pages)/
│   │   │   │   │   ├── (confs)/
│   │   │   │   │   │   ├── nextjs-conf-25/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── react-advanced-25/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── react-paris/
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── _landing/
│   │   │   │   │   │   ├── bundle-size.tsx
│   │   │   │   │   │   ├── contributors.tsx
│   │   │   │   │   │   ├── demo.client.tsx
│   │   │   │   │   │   ├── demo.tsx
│   │   │   │   │   │   ├── dependents.tsx
│   │   │   │   │   │   ├── features.tsx
│   │   │   │   │   │   ├── gha-status.tsx
│   │   │   │   │   │   ├── hero.tsx
│   │   │   │   │   │   ├── page-footer.tsx
│   │   │   │   │   │   ├── quotes/
│   │   │   │   │   │   │   └── quotes-section.tsx
│   │   │   │   │   │   ├── sponsors.tsx
│   │   │   │   │   │   └── works-with.tsx
│   │   │   │   │   ├── blog/
│   │   │   │   │   │   ├── [slug]/
│   │   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   │   └── author.tsx
│   │   │   │   │   │   │   ├── opengraph-image.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── twitter-image.tsx
│   │   │   │   │   │   ├── _lib/
│   │   │   │   │   │   │   └── source.ts
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── rss.xml/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   ├── stats/
│   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   ├── downloads.client.tsx
│   │   │   │   │   │   │   ├── downloads.tsx
│   │   │   │   │   │   │   ├── graph.skeleton.tsx
│   │   │   │   │   │   │   ├── partial-line.tsx
│   │   │   │   │   │   │   ├── stars.client.tsx
│   │   │   │   │   │   │   ├── stars.gazers-list.tsx
│   │   │   │   │   │   │   ├── stars.tsx
│   │   │   │   │   │   │   ├── versions.tsx
│   │   │   │   │   │   │   ├── widget.skeleton.tsx
│   │   │   │   │   │   │   └── widget.tsx
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   ├── format.ts
│   │   │   │   │   │   │   ├── github.ts
│   │   │   │   │   │   │   ├── npm.ts
│   │   │   │   │   │   │   ├── svg.ts
│   │   │   │   │   │   │   └── versions.ts
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── searchParams.ts
│   │   │   │   │   └── users/
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── api/
│   │   │   │   │   ├── isr/
│   │   │   │   │   │   ├── .gitignore
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── search/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── banners.tsx
│   │   │   │   ├── docs/
│   │   │   │   │   ├── [[...slug]]/
│   │   │   │   │   │   └── page.tsx
│   │   │   │   │   └── layout.tsx
│   │   │   │   ├── global-error.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── not-found.tsx
│   │   │   │   ├── playground/
│   │   │   │   │   ├── (demos)/
│   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   └── source-on-github.tsx
│   │   │   │   │   │   ├── basic-counter/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── batching/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── demos.ts
│   │   │   │   │   │   ├── hex-colors/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   ├── pagination/
│   │   │   │   │   │   │   ├── api.ts
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── pagination-controls.client.tsx
│   │   │   │   │   │   │   ├── pagination-controls.server.tsx
│   │   │   │   │   │   │   ├── product.tsx
│   │   │   │   │   │   │   ├── rendering-controls.tsx
│   │   │   │   │   │   │   └── search-params.ts
│   │   │   │   │   │   └── tic-tac-toe/
│   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── _demos/
│   │   │   │   │   │   ├── builder-pattern/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── compound-parsers/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── crosslink/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── custom-parser/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── parsers/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── pretty-urls/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-359/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-376/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-907/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── server-side-parsing/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── parser.ts
│   │   │   │   │   │   └── throttling/
│   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │       ├── page.tsx
│   │   │   │   │   │       └── parsers.ts
│   │   │   │   │   ├── debug-control.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   └── page.tsx
│   │   │   │   ├── registry/
│   │   │   │   │   ├── [name]/
│   │   │   │   │   │   ├── author.tsx
│   │   │   │   │   │   ├── opengraph-image.tsx
│   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   └── twitter-image.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── rss.xml/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── robots.ts
│   │   │   │   ├── sitemap.ts
│   │   │   │   ├── source.ts
│   │   │   │   └── styles/
│   │   │   │       └── tweaks.css
│   │   │   ├── components/
│   │   │   │   ├── 47ng.tsx
│   │   │   │   ├── ai/
│   │   │   │   │   └── page-actions.tsx
│   │   │   │   ├── audience.tsx
│   │   │   │   ├── code-block-defs.ts
│   │   │   │   ├── code-block-highlighter.skeleton.ts
│   │   │   │   ├── code-block-highlighter.ts
│   │   │   │   ├── code-block.client.tsx
│   │   │   │   ├── code-block.tsx
│   │   │   │   ├── countdown.tsx
│   │   │   │   ├── favicon.tsx
│   │   │   │   ├── feature-support-matrix.tsx
│   │   │   │   ├── frameworks.client.tsx
│   │   │   │   ├── frameworks.tsx
│   │   │   │   ├── github-profile.tsx
│   │   │   │   ├── kibo-ui/
│   │   │   │   │   └── contribution-graph/
│   │   │   │   │       └── index.tsx
│   │   │   │   ├── link-tree.tsx
│   │   │   │   ├── logo.tsx
│   │   │   │   ├── og-image.tsx
│   │   │   │   ├── query-spy.tsx
│   │   │   │   ├── querystring.tsx
│   │   │   │   ├── quote.tsx
│   │   │   │   ├── react-paris.tsx
│   │   │   │   ├── release-contribution-graph.client.tsx
│   │   │   │   ├── release-contribution-graph.tsx
│   │   │   │   ├── responsive-helpers.tsx
│   │   │   │   ├── shared-layout.tsx
│   │   │   │   ├── sidebar-footer.tsx
│   │   │   │   ├── typography.tsx
│   │   │   │   ├── ui/
│   │   │   │   │   ├── badge.tsx
│   │   │   │   │   ├── breadcrumb.tsx
│   │   │   │   │   ├── button.tsx
│   │   │   │   │   ├── card.tsx
│   │   │   │   │   ├── chart.tsx
│   │   │   │   │   ├── checkbox.tsx
│   │   │   │   │   ├── input.tsx
│   │   │   │   │   ├── label.tsx
│   │   │   │   │   ├── pagination.tsx
│   │   │   │   │   ├── popover.tsx
│   │   │   │   │   ├── pr-line.tsx
│   │   │   │   │   ├── select.tsx
│   │   │   │   │   ├── separator.tsx
│   │   │   │   │   ├── slider.tsx
│   │   │   │   │   ├── switch.tsx
│   │   │   │   │   ├── tabs.tsx
│   │   │   │   │   ├── toggle-group.tsx
│   │   │   │   │   ├── toggle.tsx
│   │   │   │   │   ├── tooltip-popover.tsx
│   │   │   │   │   └── tooltip.tsx
│   │   │   │   └── vercel-oss-badge.tsx
│   │   │   ├── instrumentation-client.ts
│   │   │   ├── instrumentation.ts
│   │   │   ├── lib/
│   │   │   │   ├── get-last-modified.ts
│   │   │   │   ├── get-llm-text.ts
│   │   │   │   ├── remark-audience.ts
│   │   │   │   ├── typed-links.ts
│   │   │   │   ├── url.ts
│   │   │   │   └── utils.ts
│   │   │   └── registry/
│   │   │       ├── assemble.ts
│   │   │       ├── items/
│   │   │       │   ├── adapter-inertia.json
│   │   │       │   ├── adapter-inertia.md
│   │   │       │   ├── adapter-onejs.json
│   │   │       │   ├── adapter-onejs.md
│   │   │       │   ├── adapter-onejs.source
│   │   │       │   ├── adapter-react-router-v5.json
│   │   │       │   ├── adapter-react-router-v5.md
│   │   │       │   ├── adapter-react-router-v5.source
│   │   │       │   ├── adapter-waku.json
│   │   │       │   ├── adapter-waku.md
│   │   │       │   ├── next-typed-links.json
│   │   │       │   └── next-typed-links.md
│   │   │       ├── read.ts
│   │   │       ├── remote/
│   │   │       │   └── .gitignore
│   │   │       └── schemas.ts
│   │   ├── tsconfig.json
│   │   └── turbo.json
│   ├── e2e/
│   │   ├── next/
│   │   │   ├── .gitignore
│   │   │   ├── next-env.d.ts
│   │   │   ├── next.config.mjs
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── scripts/
│   │   │   │   └── cache-components-codemod.ts
│   │   │   ├── specs/
│   │   │   │   ├── cache.spec.ts
│   │   │   │   ├── deferred.spec.ts
│   │   │   │   ├── multitenant.spec.ts
│   │   │   │   ├── persist-across-navigation.spec.ts
│   │   │   │   ├── push.spec.ts
│   │   │   │   ├── referential-equality.spec.ts
│   │   │   │   ├── remapped-keys.spec.ts
│   │   │   │   ├── repros.spec.ts
│   │   │   │   ├── rewrites.spec.ts
│   │   │   │   ├── routing-tour.spec.ts
│   │   │   │   ├── shared/
│   │   │   │   │   ├── basic-io-agnostic.spec.ts
│   │   │   │   │   ├── debounce.spec.ts
│   │   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   │   ├── hash-preservation.spec.ts
│   │   │   │   │   ├── loader.spec.ts
│   │   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   └── stitching.spec.ts
│   │   │   │   ├── shared.spec.ts
│   │   │   │   ├── transitions.spec.ts
│   │   │   │   ├── useQueryState.spec.ts
│   │   │   │   ├── useQueryStates-clear-all.spec.ts
│   │   │   │   ├── useQueryStates.spec.ts
│   │   │   │   └── useSearchParams.spec.ts
│   │   │   ├── src/
│   │   │   │   ├── app/
│   │   │   │   │   ├── api/
│   │   │   │   │   │   └── app/
│   │   │   │   │   │       └── loader/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   ├── app/
│   │   │   │   │   │   ├── (shared)/
│   │   │   │   │   │   │   ├── basic-io/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── conditional-rendering/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── debounce/
│   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── dynamic-segments/
│   │   │   │   │   │   │   │   ├── catch-all/
│   │   │   │   │   │   │   │   │   └── [...segments]/
│   │   │   │   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   │   └── [segment]/
│   │   │   │   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   └── optional-catch-all/
│   │   │   │   │   │   │   │       └── [[...segments]]/
│   │   │   │   │   │   │   │           ├── client.tsx
│   │   │   │   │   │   │   │           └── page.tsx
│   │   │   │   │   │   │   ├── flush-after-navigate/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── end/
│   │   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   │   └── start/
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── end/
│   │   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │   │       └── start/
│   │   │   │   │   │   │   │           └── page.tsx
│   │   │   │   │   │   │   ├── form/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── hash-preservation/
│   │   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── history-sync/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── json/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── life-and-death/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── linking/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── other/
│   │   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── native-array/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── popstate-queue-reset/
│   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── pretty-urls/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── push/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── dynamic/
│   │   │   │   │   │   │   │       │   └── [route]/
│   │   │   │   │   │   │   │       │       └── page.tsx
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── rate-limits/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── referential-stability/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── render-count/
│   │   │   │   │   │   │   │   └── [hook]/
│   │   │   │   │   │   │   │       └── [shallow]/
│   │   │   │   │   │   │   │           └── [history]/
│   │   │   │   │   │   │   │               └── [startTransition]/
│   │   │   │   │   │   │   │                   └── page.tsx
│   │   │   │   │   │   │   ├── repro-1365/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── repro-359/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── repro-982/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── routing/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   ├── other/
│   │   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       ├── other/
│   │   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   ├── scroll/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── shallow/
│   │   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   └── stitching/
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── agnostic/
│   │   │   │   │   │   │   ├── basic-io/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── layout.tsx
│   │   │   │   │   │   ├── cache/
│   │   │   │   │   │   │   ├── all.tsx
│   │   │   │   │   │   │   ├── get.tsx
│   │   │   │   │   │   │   ├── layout.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   ├── searchParams.ts
│   │   │   │   │   │   │   └── set.tsx
│   │   │   │   │   │   ├── deferred/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── loader/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── multitenant/
│   │   │   │   │   │   │   └── [tenant]/
│   │   │   │   │   │   │       ├── client-tenant.tsx
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── persist-across-navigation/
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── b/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── client.tsx
│   │   │   │   │   │   ├── push/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   ├── page.tsx
│   │   │   │   │   │   │   └── searchParams.ts
│   │   │   │   │   │   ├── referential-equality/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── remapped-keys/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-1099/
│   │   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── useQueryStates/
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── repro-1293/
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── b/
│   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   ├── repro-388/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-498/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-542/
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── b/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── client.tsx
│   │   │   │   │   │   ├── repro-630/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-758/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-760/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── repro-774/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── rewrites/
│   │   │   │   │   │   │   └── destination/
│   │   │   │   │   │   │       ├── client.tsx
│   │   │   │   │   │   │       ├── page.tsx
│   │   │   │   │   │   │       └── searchParams.ts
│   │   │   │   │   │   ├── routing-tour/
│   │   │   │   │   │   │   ├── _components/
│   │   │   │   │   │   │   │   ├── parsers.ts
│   │   │   │   │   │   │   │   └── view.tsx
│   │   │   │   │   │   │   ├── a/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── b/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── c/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   ├── d/
│   │   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   │   └── start/
│   │   │   │   │   │   │       ├── client/
│   │   │   │   │   │   │       │   └── page.tsx
│   │   │   │   │   │   │       └── server/
│   │   │   │   │   │   │           └── page.tsx
│   │   │   │   │   │   ├── template/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── transitions/
│   │   │   │   │   │   │   ├── client.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── useQueryState/
│   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── useQueryStates/
│   │   │   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   │   │   └── [route]/
│   │   │   │   │   │   │   │       └── page.tsx
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   ├── useQueryStates-clear-all/
│   │   │   │   │   │   │   └── page.tsx
│   │   │   │   │   │   └── useSearchParams/
│   │   │   │   │   │       └── page.tsx
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── providers.tsx
│   │   │   │   ├── components/
│   │   │   │   │   └── pages-ready-wrapper.tsx
│   │   │   │   ├── middleware.ts
│   │   │   │   └── pages/
│   │   │   │       ├── _app.tsx
│   │   │   │       ├── api/
│   │   │   │       │   └── pages/
│   │   │   │       │       └── loader.ts
│   │   │   │       └── pages/
│   │   │   │           ├── agnostic/
│   │   │   │           │   └── basic-io.tsx
│   │   │   │           ├── basic-io/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── conditional-rendering/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── debounce/
│   │   │   │           │   ├── index.tsx
│   │   │   │           │   └── other.tsx
│   │   │   │           ├── dynamic-segments/
│   │   │   │           │   ├── catch-all/
│   │   │   │           │   │   └── [...segments].tsx
│   │   │   │           │   ├── dynamic/
│   │   │   │           │   │   └── [segment].tsx
│   │   │   │           │   └── optional-catch-all/
│   │   │   │           │       └── [[...segments]].tsx
│   │   │   │           ├── flush-after-navigate/
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── end.tsx
│   │   │   │           │   │   └── start.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── end.tsx
│   │   │   │           │       └── start.tsx
│   │   │   │           ├── form/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── hash-preservation/
│   │   │   │           │   ├── dynamic/
│   │   │   │           │   │   └── [route]/
│   │   │   │           │   │       └── index.tsx
│   │   │   │           │   └── index.tsx
│   │   │   │           ├── history-sync.tsx
│   │   │   │           ├── json.tsx
│   │   │   │           ├── life-and-death.tsx
│   │   │   │           ├── linking/
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── index.tsx
│   │   │   │           │   │   └── other.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── index.tsx
│   │   │   │           │       └── other.tsx
│   │   │   │           ├── loader.tsx
│   │   │   │           ├── middleware.tsx
│   │   │   │           ├── multitenant/
│   │   │   │           │   └── [tenant].tsx
│   │   │   │           ├── native-array.tsx
│   │   │   │           ├── popstate-queue-reset/
│   │   │   │           │   ├── index.tsx
│   │   │   │           │   └── other.tsx
│   │   │   │           ├── pretty-urls.tsx
│   │   │   │           ├── push/
│   │   │   │           │   ├── index.tsx
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── dynamic/
│   │   │   │           │   │   │   └── [route]/
│   │   │   │           │   │   │       └── index.tsx
│   │   │   │           │   │   └── index.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── dynamic/
│   │   │   │           │       │   └── [route]/
│   │   │   │           │       │       └── index.tsx
│   │   │   │           │       └── index.tsx
│   │   │   │           ├── rate-limits.tsx
│   │   │   │           ├── referential-stability/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── render-count/
│   │   │   │           │   └── [hook]/
│   │   │   │           │       └── [shallow]/
│   │   │   │           │           └── [history]/
│   │   │   │           │               └── [startTransition]/
│   │   │   │           │                   └── index.tsx
│   │   │   │           ├── repro-1099/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── repro-1293/
│   │   │   │           │   ├── a.tsx
│   │   │   │           │   └── b.tsx
│   │   │   │           ├── repro-1365.tsx
│   │   │   │           ├── repro-359.tsx
│   │   │   │           ├── repro-982.tsx
│   │   │   │           ├── routing/
│   │   │   │           │   ├── useQueryState/
│   │   │   │           │   │   ├── index.tsx
│   │   │   │           │   │   └── other.tsx
│   │   │   │           │   └── useQueryStates/
│   │   │   │           │       ├── index.tsx
│   │   │   │           │       └── other.tsx
│   │   │   │           ├── scroll.tsx
│   │   │   │           ├── shallow/
│   │   │   │           │   ├── useQueryState.tsx
│   │   │   │           │   └── useQueryStates.tsx
│   │   │   │           ├── stitching.tsx
│   │   │   │           ├── useQueryState/
│   │   │   │           │   ├── dynamic/
│   │   │   │           │   │   └── [route]/
│   │   │   │           │   │       └── index.tsx
│   │   │   │           │   └── index.tsx
│   │   │   │           └── useQueryStates/
│   │   │   │               ├── dynamic/
│   │   │   │               │   └── [route]/
│   │   │   │               │       └── index.tsx
│   │   │   │               └── index.tsx
│   │   │   ├── tsconfig.json
│   │   │   └── turbo.json
│   │   ├── package.json
│   │   ├── react/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── specs/
│   │   │   │   ├── shared/
│   │   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   ├── referential-stability.spec.ts
│   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   ├── routing.spec.ts
│   │   │   │   │   ├── scroll.spec.ts
│   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   └── stitching.spec.ts
│   │   │   │   └── shared.spec.ts
│   │   │   ├── src/
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── main.tsx
│   │   │   │   ├── routes/
│   │   │   │   │   ├── basic-io.useQueryState.tsx
│   │   │   │   │   ├── basic-io.useQueryStates.tsx
│   │   │   │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │   │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │   │   │   ├── form.useQueryState.tsx
│   │   │   │   │   ├── form.useQueryStates.tsx
│   │   │   │   │   ├── hash-preservation.tsx
│   │   │   │   │   ├── history-sync.tsx
│   │   │   │   │   ├── json.tsx
│   │   │   │   │   ├── key-isolation.useQueryState.tsx
│   │   │   │   │   ├── key-isolation.useQueryStates.tsx
│   │   │   │   │   ├── life-and-death.tsx
│   │   │   │   │   ├── linking.useQueryState.other.tsx
│   │   │   │   │   ├── linking.useQueryState.tsx
│   │   │   │   │   ├── linking.useQueryStates.other.tsx
│   │   │   │   │   ├── linking.useQueryStates.tsx
│   │   │   │   │   ├── native-array.tsx
│   │   │   │   │   ├── pretty-urls.tsx
│   │   │   │   │   ├── push.useQueryState.tsx
│   │   │   │   │   ├── push.useQueryStates.tsx
│   │   │   │   │   ├── rate-limits.tsx
│   │   │   │   │   ├── referential-stability.useQueryState.tsx
│   │   │   │   │   ├── referential-stability.useQueryStates.tsx
│   │   │   │   │   ├── render-count.tsx
│   │   │   │   │   ├── repro-1099.useQueryState.tsx
│   │   │   │   │   ├── repro-1099.useQueryStates.tsx
│   │   │   │   │   ├── repro-1365.tsx
│   │   │   │   │   ├── repro-359.tsx
│   │   │   │   │   ├── repro-982.tsx
│   │   │   │   │   ├── routing.useQueryState.other.tsx
│   │   │   │   │   ├── routing.useQueryState.tsx
│   │   │   │   │   ├── routing.useQueryStates.other.tsx
│   │   │   │   │   ├── routing.useQueryStates.tsx
│   │   │   │   │   ├── scroll.tsx
│   │   │   │   │   ├── shallow.useQueryState.tsx
│   │   │   │   │   ├── shallow.useQueryStates.tsx
│   │   │   │   │   └── stitching.tsx
│   │   │   │   ├── routes.tsx
│   │   │   │   └── vite-env.d.ts
│   │   │   ├── tsconfig.app.json
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   ├── turbo.json
│   │   │   └── vite.config.ts
│   │   ├── react-router/
│   │   │   ├── package.json
│   │   │   ├── v5/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── README.md
│   │   │   │   ├── index.html
│   │   │   │   ├── package.json
│   │   │   │   ├── playwright.config.ts
│   │   │   │   ├── specs/
│   │   │   │   │   ├── shared/
│   │   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   │   └── stitching.spec.ts
│   │   │   │   │   └── shared.spec.ts
│   │   │   │   ├── src/
│   │   │   │   │   ├── adapter.ts
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── main.tsx
│   │   │   │   │   ├── react-router.tsx
│   │   │   │   │   ├── routes/
│   │   │   │   │   │   ├── basic-io.useQueryState.tsx
│   │   │   │   │   │   ├── basic-io.useQueryStates.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │   │   │   │   ├── fog-of-war._index.tsx
│   │   │   │   │   │   ├── fog-of-war.result.tsx
│   │   │   │   │   │   ├── form.useQueryState.tsx
│   │   │   │   │   │   ├── form.useQueryStates.tsx
│   │   │   │   │   │   ├── hash-preservation.tsx
│   │   │   │   │   │   ├── history-sync.tsx
│   │   │   │   │   │   ├── json.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryState.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryStates.tsx
│   │   │   │   │   │   ├── life-and-death.tsx
│   │   │   │   │   │   ├── linking.useQueryState.other.tsx
│   │   │   │   │   │   ├── linking.useQueryState.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.other.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.tsx
│   │   │   │   │   │   ├── native-array.tsx
│   │   │   │   │   │   ├── pretty-urls.tsx
│   │   │   │   │   │   ├── push.useQueryState.tsx
│   │   │   │   │   │   ├── push.useQueryStates.tsx
│   │   │   │   │   │   ├── rate-limits.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryState.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryStates.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryState.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryStates.tsx
│   │   │   │   │   │   ├── repro-359.tsx
│   │   │   │   │   │   ├── repro-982.tsx
│   │   │   │   │   │   ├── routing.useQueryState.other.tsx
│   │   │   │   │   │   ├── routing.useQueryState.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.other.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.tsx
│   │   │   │   │   │   ├── scroll.tsx
│   │   │   │   │   │   └── stitching.tsx
│   │   │   │   │   └── vite-env.d.ts
│   │   │   │   ├── tsconfig.app.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── tsconfig.node.json
│   │   │   │   ├── turbo.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── v6/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── README.md
│   │   │   │   ├── index.html
│   │   │   │   ├── package.json
│   │   │   │   ├── playwright.config.ts
│   │   │   │   ├── specs/
│   │   │   │   │   ├── repro-839.spec.ts
│   │   │   │   │   ├── shared/
│   │   │   │   │   │   ├── debounce.spec.ts
│   │   │   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   │   │   ├── loader.spec.ts
│   │   │   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   │   └── stitching.spec.ts
│   │   │   │   │   └── shared.spec.ts
│   │   │   │   ├── src/
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── main.tsx
│   │   │   │   │   ├── react-router.tsx
│   │   │   │   │   ├── routes/
│   │   │   │   │   │   ├── basic-io.useQueryState.tsx
│   │   │   │   │   │   ├── basic-io.useQueryStates.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │   │   │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │   │   │   │   ├── debounce.other.tsx
│   │   │   │   │   │   ├── debounce.tsx
│   │   │   │   │   │   ├── dynamic-segments.catch-all.$.tsx
│   │   │   │   │   │   ├── dynamic-segments.dynamic.$segment.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryState.end.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryState.start.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryStates.end.tsx
│   │   │   │   │   │   ├── flush-after-navigate.useQueryStates.start.tsx
│   │   │   │   │   │   ├── fog-of-war._index.tsx
│   │   │   │   │   │   ├── fog-of-war.result.tsx
│   │   │   │   │   │   ├── form.useQueryState.tsx
│   │   │   │   │   │   ├── form.useQueryStates.tsx
│   │   │   │   │   │   ├── hash-preservation.tsx
│   │   │   │   │   │   ├── history-sync.tsx
│   │   │   │   │   │   ├── json.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryState.tsx
│   │   │   │   │   │   ├── key-isolation.useQueryStates.tsx
│   │   │   │   │   │   ├── life-and-death.tsx
│   │   │   │   │   │   ├── linking.useQueryState.other.tsx
│   │   │   │   │   │   ├── linking.useQueryState.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.other.tsx
│   │   │   │   │   │   ├── linking.useQueryStates.tsx
│   │   │   │   │   │   ├── loader.tsx
│   │   │   │   │   │   ├── native-array.tsx
│   │   │   │   │   │   ├── popstate-queue-reset.other.tsx
│   │   │   │   │   │   ├── popstate-queue-reset.tsx
│   │   │   │   │   │   ├── pretty-urls.tsx
│   │   │   │   │   │   ├── push.useQueryState.tsx
│   │   │   │   │   │   ├── push.useQueryStates.tsx
│   │   │   │   │   │   ├── rate-limits.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryState.tsx
│   │   │   │   │   │   ├── referential-stability.useQueryStates.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │   │   │   │   ├── render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryState.tsx
│   │   │   │   │   │   ├── repro-1099.useQueryStates.tsx
│   │   │   │   │   │   ├── repro-1293.a.tsx
│   │   │   │   │   │   ├── repro-1293.b.tsx
│   │   │   │   │   │   ├── repro-1365.tsx
│   │   │   │   │   │   ├── repro-359.tsx
│   │   │   │   │   │   ├── repro-839.tsx
│   │   │   │   │   │   ├── repro-982.tsx
│   │   │   │   │   │   ├── routing.useQueryState.other.tsx
│   │   │   │   │   │   ├── routing.useQueryState.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.other.tsx
│   │   │   │   │   │   ├── routing.useQueryStates.tsx
│   │   │   │   │   │   ├── scroll.tsx
│   │   │   │   │   │   ├── shallow.useQueryState.tsx
│   │   │   │   │   │   ├── shallow.useQueryStates.tsx
│   │   │   │   │   │   └── stitching.tsx
│   │   │   │   │   └── vite-env.d.ts
│   │   │   │   ├── tsconfig.app.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── tsconfig.node.json
│   │   │   │   ├── turbo.json
│   │   │   │   └── vite.config.ts
│   │   │   └── v7/
│   │   │       ├── .gitignore
│   │   │       ├── README.md
│   │   │       ├── app/
│   │   │       │   ├── layout.tsx
│   │   │       │   ├── root.tsx
│   │   │       │   ├── routes/
│   │   │       │   │   ├── basic-io.useQueryState.tsx
│   │   │       │   │   ├── basic-io.useQueryStates.tsx
│   │   │       │   │   ├── conditional-rendering.useQueryState.tsx
│   │   │       │   │   ├── conditional-rendering.useQueryStates.tsx
│   │   │       │   │   ├── debounce.other.tsx
│   │   │       │   │   ├── debounce.tsx
│   │   │       │   │   ├── dynamic-segments.catch-all.$.tsx
│   │   │       │   │   ├── dynamic-segments.dynamic.$segment.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryState.end.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryState.start.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryStates.end.tsx
│   │   │       │   │   ├── flush-after-navigate.useQueryStates.start.tsx
│   │   │       │   │   ├── fog-of-war._index.tsx
│   │   │       │   │   ├── fog-of-war.result.tsx
│   │   │       │   │   ├── form.useQueryState.tsx
│   │   │       │   │   ├── form.useQueryStates.tsx
│   │   │       │   │   ├── hash-preservation.tsx
│   │   │       │   │   ├── history-sync.tsx
│   │   │       │   │   ├── json.tsx
│   │   │       │   │   ├── key-isolation.useQueryState.tsx
│   │   │       │   │   ├── key-isolation.useQueryStates.tsx
│   │   │       │   │   ├── life-and-death.tsx
│   │   │       │   │   ├── linking.useQueryState.other.tsx
│   │   │       │   │   ├── linking.useQueryState.tsx
│   │   │       │   │   ├── linking.useQueryStates.other.tsx
│   │   │       │   │   ├── linking.useQueryStates.tsx
│   │   │       │   │   ├── loader.tsx
│   │   │       │   │   ├── native-array.tsx
│   │   │       │   │   ├── popstate-queue-reset.other.tsx
│   │   │       │   │   ├── popstate-queue-reset.tsx
│   │   │       │   │   ├── pretty-urls.tsx
│   │   │       │   │   ├── push.useQueryState.tsx
│   │   │       │   │   ├── push.useQueryStates.tsx
│   │   │       │   │   ├── rate-limits.tsx
│   │   │       │   │   ├── referential-stability.useQueryState.tsx
│   │   │       │   │   ├── referential-stability.useQueryStates.tsx
│   │   │       │   │   ├── render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
│   │   │       │   │   ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │       │   │   ├── render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
│   │   │       │   │   ├── repro-1099.useQueryState.tsx
│   │   │       │   │   ├── repro-1099.useQueryStates.tsx
│   │   │       │   │   ├── repro-1293.a.tsx
│   │   │       │   │   ├── repro-1293.b.tsx
│   │   │       │   │   ├── repro-1365.tsx
│   │   │       │   │   ├── repro-359.tsx
│   │   │       │   │   ├── repro-839.tsx
│   │   │       │   │   ├── repro-982.tsx
│   │   │       │   │   ├── routing.useQueryState.other.tsx
│   │   │       │   │   ├── routing.useQueryState.tsx
│   │   │       │   │   ├── routing.useQueryStates.other.tsx
│   │   │       │   │   ├── routing.useQueryStates.tsx
│   │   │       │   │   ├── scroll.tsx
│   │   │       │   │   ├── shallow.useQueryState.tsx
│   │   │       │   │   ├── shallow.useQueryStates.tsx
│   │   │       │   │   └── stitching.tsx
│   │   │       │   └── routes.ts
│   │   │       ├── package.json
│   │   │       ├── playwright.config.ts
│   │   │       ├── react-router.config.ts
│   │   │       ├── server.mjs
│   │   │       ├── specs/
│   │   │       │   ├── repro-839.spec.ts
│   │   │       │   ├── shared/
│   │   │       │   │   ├── debounce.spec.ts
│   │   │       │   │   ├── dynamic-segments.spec.ts
│   │   │       │   │   ├── flush-after-navigate.spec.ts
│   │   │       │   │   ├── fog-of-war.spec.ts
│   │   │       │   │   ├── key-isolation.spec.ts
│   │   │       │   │   ├── loader.spec.ts
│   │   │       │   │   ├── popstate-queue-reset.spec.ts
│   │   │       │   │   ├── push.spec.ts
│   │   │       │   │   ├── render-count.spec.ts
│   │   │       │   │   ├── repro-1099.spec.ts
│   │   │       │   │   ├── repro-1293.spec.ts
│   │   │       │   │   ├── repro-1365.spec.ts
│   │   │       │   │   ├── repro-359.spec.ts
│   │   │       │   │   ├── repro-982.spec.ts
│   │   │       │   │   ├── shallow.spec.ts
│   │   │       │   │   └── stitching.spec.ts
│   │   │       │   └── shared.spec.ts
│   │   │       ├── tsconfig.json
│   │   │       ├── turbo.json
│   │   │       └── vite.config.ts
│   │   ├── remix/
│   │   │   ├── .eslintrc.cjs
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── app/
│   │   │   │   ├── entry.client.tsx
│   │   │   │   ├── entry.server.tsx
│   │   │   │   ├── layout.tsx
│   │   │   │   ├── root.tsx
│   │   │   │   └── routes/
│   │   │   │       ├── basic-io.useQueryState.tsx
│   │   │   │       ├── basic-io.useQueryStates.tsx
│   │   │   │       ├── conditional-rendering.useQueryState.tsx
│   │   │   │       ├── conditional-rendering.useQueryStates.tsx
│   │   │   │       ├── debounce-other.tsx
│   │   │   │       ├── debounce.tsx
│   │   │   │       ├── dynamic-segments.catch-all.$.tsx
│   │   │   │       ├── dynamic-segments.dynamic.$segment.tsx
│   │   │   │       ├── flush-after-navigate.useQueryState.end.tsx
│   │   │   │       ├── flush-after-navigate.useQueryState.start.tsx
│   │   │   │       ├── flush-after-navigate.useQueryStates.end.tsx
│   │   │   │       ├── flush-after-navigate.useQueryStates.start.tsx
│   │   │   │       ├── fog-of-war._index.tsx
│   │   │   │       ├── fog-of-war.result.tsx
│   │   │   │       ├── form.useQueryState.tsx
│   │   │   │       ├── form.useQueryStates.tsx
│   │   │   │       ├── hash-preservation.tsx
│   │   │   │       ├── history-sync.tsx
│   │   │   │       ├── json.tsx
│   │   │   │       ├── key-isolation.useQueryState.tsx
│   │   │   │       ├── key-isolation.useQueryStates.tsx
│   │   │   │       ├── life-and-death.tsx
│   │   │   │       ├── linking.useQueryState.other.tsx
│   │   │   │       ├── linking.useQueryState.tsx
│   │   │   │       ├── linking.useQueryStates.other.tsx
│   │   │   │       ├── linking.useQueryStates.tsx
│   │   │   │       ├── loader.tsx
│   │   │   │       ├── native-array.tsx
│   │   │   │       ├── popstate-queue-reset-other.tsx
│   │   │   │       ├── popstate-queue-reset.tsx
│   │   │   │       ├── pretty-urls.tsx
│   │   │   │       ├── push.useQueryState.tsx
│   │   │   │       ├── push.useQueryStates.tsx
│   │   │   │       ├── rate-limits.tsx
│   │   │   │       ├── referential-stability.useQueryState.tsx
│   │   │   │       ├── referential-stability.useQueryStates.tsx
│   │   │   │       ├── render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
│   │   │   │       ├── render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
│   │   │   │       ├── render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
│   │   │   │       ├── repro-1099.useQueryState.tsx
│   │   │   │       ├── repro-1099.useQueryStates.tsx
│   │   │   │       ├── repro-1293.a.tsx
│   │   │   │       ├── repro-1293.b.tsx
│   │   │   │       ├── repro-1365.tsx
│   │   │   │       ├── repro-359.tsx
│   │   │   │       ├── repro-839.tsx
│   │   │   │       ├── repro-982.tsx
│   │   │   │       ├── routing.useQueryState.other.tsx
│   │   │   │       ├── routing.useQueryState.tsx
│   │   │   │       ├── routing.useQueryStates.other.tsx
│   │   │   │       ├── routing.useQueryStates.tsx
│   │   │   │       ├── scroll.tsx
│   │   │   │       ├── shallow.useQueryState.tsx
│   │   │   │       ├── shallow.useQueryStates.tsx
│   │   │   │       └── stitching.tsx
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── specs/
│   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   ├── repro-839.spec.ts
│   │   │   │   ├── shared/
│   │   │   │   │   ├── debounce.spec.ts
│   │   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   │   ├── loader.spec.ts
│   │   │   │   │   ├── push.spec.ts
│   │   │   │   │   ├── render-count.spec.ts
│   │   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   │   ├── repro-359.spec.ts
│   │   │   │   │   ├── repro-982.spec.ts
│   │   │   │   │   ├── shallow.spec.ts
│   │   │   │   │   └── stitching.spec.ts
│   │   │   │   └── shared.spec.ts
│   │   │   ├── tsconfig.json
│   │   │   ├── turbo.json
│   │   │   └── vite.config.ts
│   │   ├── shared/
│   │   │   ├── components/
│   │   │   │   ├── display.tsx
│   │   │   │   ├── hydration-marker.tsx
│   │   │   │   ├── link.tsx
│   │   │   │   ├── null-detector.tsx
│   │   │   │   └── router.tsx
│   │   │   ├── define-test.ts
│   │   │   ├── lib/
│   │   │   │   └── options.ts
│   │   │   ├── package.json
│   │   │   ├── playwright/
│   │   │   │   ├── agent-reporter.ts
│   │   │   │   ├── expect-url.ts
│   │   │   │   ├── log-spy.ts
│   │   │   │   ├── navigate.ts
│   │   │   │   ├── reporter.ts
│   │   │   │   └── url-spy.ts
│   │   │   ├── playwright.config.ts
│   │   │   ├── shared.spec.ts
│   │   │   ├── specs/
│   │   │   │   ├── basic-io.spec.ts
│   │   │   │   ├── basic-io.tsx
│   │   │   │   ├── conditional-rendering.spec.ts
│   │   │   │   ├── conditional-rendering.tsx
│   │   │   │   ├── debounce-client.tsx
│   │   │   │   ├── debounce-server.tsx
│   │   │   │   ├── debounce.defs.ts
│   │   │   │   ├── debounce.spec.ts
│   │   │   │   ├── dynamic-segments.spec.ts
│   │   │   │   ├── dynamic-segments.tsx
│   │   │   │   ├── flush-after-navigate.defs.ts
│   │   │   │   ├── flush-after-navigate.spec.ts
│   │   │   │   ├── flush-after-navigate.tsx
│   │   │   │   ├── form.spec.ts
│   │   │   │   ├── form.tsx
│   │   │   │   ├── hash-preservation.spec.ts
│   │   │   │   ├── hash-preservation.tsx
│   │   │   │   ├── history-sync.spec.ts
│   │   │   │   ├── history-sync.tsx
│   │   │   │   ├── json.spec.ts
│   │   │   │   ├── json.tsx
│   │   │   │   ├── key-isolation.spec.ts
│   │   │   │   ├── key-isolation.tsx
│   │   │   │   ├── life-and-death.spec.ts
│   │   │   │   ├── life-and-death.tsx
│   │   │   │   ├── linking.spec.ts
│   │   │   │   ├── linking.tsx
│   │   │   │   ├── loader.spec.ts
│   │   │   │   ├── loader.tsx
│   │   │   │   ├── native-array.spec.ts
│   │   │   │   ├── native-array.tsx
│   │   │   │   ├── popstate-queue-reset.defs.ts
│   │   │   │   ├── popstate-queue-reset.spec.ts
│   │   │   │   ├── popstate-queue-reset.tsx
│   │   │   │   ├── pretty-urls.spec.ts
│   │   │   │   ├── pretty-urls.tsx
│   │   │   │   ├── push.spec.ts
│   │   │   │   ├── push.tsx
│   │   │   │   ├── rate-limits.tsx
│   │   │   │   ├── react-router/
│   │   │   │   │   ├── fog-of-war.spec.ts
│   │   │   │   │   ├── fog-of-war.tsx
│   │   │   │   │   ├── repro-839-location-state-persistence.spec.ts
│   │   │   │   │   └── repro-839-location-state-persistence.tsx
│   │   │   │   ├── referential-stability.spec.ts
│   │   │   │   ├── referential-stability.tsx
│   │   │   │   ├── render-count.params.ts
│   │   │   │   ├── render-count.spec.ts
│   │   │   │   ├── render-count.tsx
│   │   │   │   ├── repro-1099.spec.ts
│   │   │   │   ├── repro-1099.tsx
│   │   │   │   ├── repro-1293.spec.ts
│   │   │   │   ├── repro-1293.tsx
│   │   │   │   ├── repro-1365.spec.ts
│   │   │   │   ├── repro-1365.tsx
│   │   │   │   ├── repro-359.spec.ts
│   │   │   │   ├── repro-359.tsx
│   │   │   │   ├── repro-982.spec.ts
│   │   │   │   ├── repro-982.tsx
│   │   │   │   ├── routing.defs.ts
│   │   │   │   ├── routing.spec.ts
│   │   │   │   ├── routing.tsx
│   │   │   │   ├── scroll.spec.ts
│   │   │   │   ├── scroll.tsx
│   │   │   │   ├── shallow.spec.ts
│   │   │   │   ├── shallow.tsx
│   │   │   │   ├── stitching.defs.ts
│   │   │   │   ├── stitching.spec.ts
│   │   │   │   └── stitching.tsx
│   │   │   └── tsconfig.json
│   │   └── tanstack-router/
│   │       ├── .cta.json
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── index.html
│   │       ├── package.json
│   │       ├── playwright.config.ts
│   │       ├── specs/
│   │       │   ├── shared/
│   │       │   │   ├── basic-io.spec.ts
│   │       │   │   ├── conditional-rendering.spec.ts
│   │       │   │   ├── form.spec.ts
│   │       │   │   ├── hash-preservation.spec.ts
│   │       │   │   ├── json.spec.ts
│   │       │   │   ├── key-isolation.spec.ts
│   │       │   │   ├── linking.spec.ts
│   │       │   │   ├── native-array.spec.ts
│   │       │   │   ├── pretty-urls.spec.ts
│   │       │   │   ├── push.spec.ts
│   │       │   │   ├── referential-stability.spec.ts
│   │       │   │   ├── repro-1099.spec.ts
│   │       │   │   ├── repro-1365.spec.ts
│   │       │   │   ├── routing.spec.ts
│   │       │   │   ├── scroll.spec.ts
│   │       │   │   └── shallow.spec.ts
│   │       │   ├── shared.spec.ts
│   │       │   └── trailing-slash.spec.ts
│   │       ├── src/
│   │       │   ├── layout.tsx
│   │       │   ├── main.tsx
│   │       │   └── routes/
│   │       │       ├── __root.tsx
│   │       │       ├── basic-io.useQueryState.tsx
│   │       │       ├── basic-io.useQueryStates.tsx
│   │       │       ├── conditional-rendering.useQueryState.tsx
│   │       │       ├── conditional-rendering.useQueryStates.tsx
│   │       │       ├── form.useQueryState.tsx
│   │       │       ├── form.useQueryStates.tsx
│   │       │       ├── hash-preservation.tsx
│   │       │       ├── history-sync.tsx
│   │       │       ├── json.tsx
│   │       │       ├── key-isolation.useQueryState.tsx
│   │       │       ├── key-isolation.useQueryStates.tsx
│   │       │       ├── life-and-death.tsx
│   │       │       ├── linking.useQueryState.other.tsx
│   │       │       ├── linking.useQueryState.tsx
│   │       │       ├── linking.useQueryStates.other.tsx
│   │       │       ├── linking.useQueryStates.tsx
│   │       │       ├── native-array.tsx
│   │       │       ├── pretty-urls.tsx
│   │       │       ├── push.useQueryState.tsx
│   │       │       ├── push.useQueryStates.tsx
│   │       │       ├── referential-stability.useQueryState.tsx
│   │       │       ├── referential-stability.useQueryStates.tsx
│   │       │       ├── repro-1099.useQueryState.tsx
│   │       │       ├── repro-1099.useQueryStates.tsx
│   │       │       ├── repro-1365.tsx
│   │       │       ├── routing.useQueryState.other.tsx
│   │       │       ├── routing.useQueryState.tsx
│   │       │       ├── routing.useQueryStates.other.tsx
│   │       │       ├── routing.useQueryStates.tsx
│   │       │       ├── scroll.tsx
│   │       │       ├── shallow.useQueryState.tsx
│   │       │       ├── shallow.useQueryStates.tsx
│   │       │       └── trailing-slash.tsx
│   │       ├── tsconfig.json
│   │       ├── turbo.json
│   │       └── vite.config.js
│   ├── examples/
│   │   ├── next-app/
│   │   │   ├── .gitignore
│   │   │   ├── README.md
│   │   │   ├── next.config.ts
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── app/
│   │   │   │   │   ├── _components/
│   │   │   │   │   │   ├── filter.tsx
│   │   │   │   │   │   ├── pagination.tsx
│   │   │   │   │   │   └── users-list.tsx
│   │   │   │   │   ├── globals.css
│   │   │   │   │   ├── layout.tsx
│   │   │   │   │   ├── page.tsx
│   │   │   │   │   └── searchParams.tsx
│   │   │   │   └── data.ts
│   │   │   └── tsconfig.json
│   │   ├── package.json
│   │   └── trpc/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── app/
│   │       │   ├── components/
│   │       │   │   ├── inverted-coordinates.tsx
│   │       │   │   └── random-coordinates.tsx
│   │       │   ├── root.tsx
│   │       │   ├── routes/
│   │       │   │   ├── api/
│   │       │   │   │   └── trpc.ts
│   │       │   │   └── index.tsx
│   │       │   ├── routes.ts
│   │       │   ├── search-params.ts
│   │       │   ├── server/
│   │       │   │   └── trpc.ts
│   │       │   └── utils/
│   │       │       └── trpc.ts
│   │       ├── package.json
│   │       ├── react-router.config.ts
│   │       ├── server.mjs
│   │       ├── tsconfig.json
│   │       └── vite.config.ts
│   ├── nuqs/
│   │   ├── .gitignore
│   │   ├── adapters/
│   │   │   ├── custom.d.ts
│   │   │   ├── next/
│   │   │   │   ├── app.d.ts
│   │   │   │   └── pages.d.ts
│   │   │   ├── next.d.ts
│   │   │   ├── react-router/
│   │   │   │   ├── v6.d.ts
│   │   │   │   └── v7.d.ts
│   │   │   ├── react-router.d.ts
│   │   │   ├── react.d.ts
│   │   │   ├── remix.d.ts
│   │   │   ├── tanstack-router.d.ts
│   │   │   └── testing.d.ts
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── prepack.sh
│   │   ├── server.d.ts
│   │   ├── src/
│   │   │   ├── adapters/
│   │   │   │   ├── custom.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── defs.ts
│   │   │   │   │   ├── key-isolation.ts
│   │   │   │   │   ├── patch-history.browser.test.ts
│   │   │   │   │   ├── patch-history.ts
│   │   │   │   │   └── react-router.ts
│   │   │   │   ├── next/
│   │   │   │   │   ├── app.ts
│   │   │   │   │   ├── impl.app.ts
│   │   │   │   │   ├── impl.pages.test.ts
│   │   │   │   │   ├── impl.pages.ts
│   │   │   │   │   └── pages.ts
│   │   │   │   ├── next.ts
│   │   │   │   ├── react-router/
│   │   │   │   │   ├── v6.ts
│   │   │   │   │   └── v7.ts
│   │   │   │   ├── react-router.ts
│   │   │   │   ├── react.ts
│   │   │   │   ├── remix.ts
│   │   │   │   ├── tanstack-router.ts
│   │   │   │   └── testing.ts
│   │   │   ├── api.test.ts
│   │   │   ├── cache.test.ts
│   │   │   ├── cache.ts
│   │   │   ├── defs.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── lib/
│   │   │   │   ├── compare.test.ts
│   │   │   │   ├── compare.ts
│   │   │   │   ├── compose.test.ts
│   │   │   │   ├── compose.ts
│   │   │   │   ├── debug.test.ts
│   │   │   │   ├── debug.ts
│   │   │   │   ├── emitter.test.ts
│   │   │   │   ├── emitter.ts
│   │   │   │   ├── errors.ts
│   │   │   │   ├── queues/
│   │   │   │   │   ├── debounce.test.ts
│   │   │   │   │   ├── debounce.ts
│   │   │   │   │   ├── rate-limiting.ts
│   │   │   │   │   ├── reset.ts
│   │   │   │   │   ├── throttle.test.ts
│   │   │   │   │   ├── throttle.ts
│   │   │   │   │   ├── useSyncExternalStores.browser.test.ts
│   │   │   │   │   └── useSyncExternalStores.ts
│   │   │   │   ├── safe-parse.ts
│   │   │   │   ├── search-params.ts
│   │   │   │   ├── sync.browser.test.tsx
│   │   │   │   ├── sync.ts
│   │   │   │   ├── timeout.test.ts
│   │   │   │   ├── timeout.ts
│   │   │   │   ├── url-encoding.browser.test.ts
│   │   │   │   ├── url-encoding.ts
│   │   │   │   ├── with-resolvers.test.ts
│   │   │   │   └── with-resolvers.ts
│   │   │   ├── loader.test.ts
│   │   │   ├── loader.ts
│   │   │   ├── parsers.test.ts
│   │   │   ├── parsers.ts
│   │   │   ├── serializer.test.ts
│   │   │   ├── serializer.ts
│   │   │   ├── standard-schema.test.ts
│   │   │   ├── standard-schema.ts
│   │   │   ├── testing.ts
│   │   │   ├── useQueryState.browser.test.tsx
│   │   │   ├── useQueryState.ts
│   │   │   ├── useQueryStates.browser.test.tsx
│   │   │   └── useQueryStates.ts
│   │   ├── testing.d.ts
│   │   ├── tests/
│   │   │   ├── cache.test-d.ts
│   │   │   ├── components/
│   │   │   │   └── repro-1099.tsx
│   │   │   ├── parsers.test-d.ts
│   │   │   ├── serializer.test-d.ts
│   │   │   ├── useQueryState.test-d.ts
│   │   │   └── useQueryStates.test-d.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   ├── turbo.json
│   │   ├── vitest.browser.setup.ts
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.ts
│   ├── res/
│   │   └── package.json
│   └── scripts/
│       ├── next-release-analyser.ts
│       ├── package.json
│       ├── release-notes-automation.test.ts
│       ├── release-notes-automation.ts
│       └── tsconfig.json
├── pnpm-workspace.yaml
└── turbo.json
Download .txt
SYMBOL INDEX (1224 symbols across 531 files)

FILE: packages/docs/content/blog/beware-the-url-type-safety-iceberg.components.tsx
  function URLComparison (line 24) | function URLComparison() {

FILE: packages/docs/content/blog/nuqs-2.5-key-isolation.client.tsx
  function KeyIsolationStyles (line 8) | function KeyIsolationStyles() {
  function DemoSkeleton (line 29) | function DemoSkeleton() {
  function WithoutKeyIsolationDemo (line 38) | function WithoutKeyIsolationDemo() {
  function WithKeyIsolationDemo (line 47) | function WithKeyIsolationDemo() {
  function Component (line 65) | function Component({ id }: { id: string }) {
  function ComponentSkeleton (line 92) | function ComponentSkeleton() {

FILE: packages/docs/content/blog/open-source-pledge-recipient.tsx
  type OpenSourcePledgeRecipientProps (line 1) | type OpenSourcePledgeRecipientProps = {
  function OpenSourcePledgeRecipient (line 6) | function OpenSourcePledgeRecipient({

FILE: packages/docs/content/docs/options.client.tsx
  function DemoSkeleton (line 11) | function DemoSkeleton() {
  function sortAlphabetically (line 21) | function sortAlphabetically(search: URLSearchParams): URLSearchParams {
  function passThrough (line 25) | function passThrough(search: URLSearchParams): URLSearchParams {
  function AlphabeticalSortDemo (line 29) | function AlphabeticalSortDemo() {
  function TimestampDemo (line 55) | function TimestampDemo() {
  function ComponentIncrement (line 75) | function ComponentIncrement({ id }: { id: string }) {
  function ComponentToggle (line 89) | function ComponentToggle({ id }: { id: string }) {
  function ComponentSkeleton (line 103) | function ComponentSkeleton() {

FILE: packages/docs/content/docs/parsers/community/effect-schema-demo.tsx
  function createSchemaParser (line 13) | function createSchemaParser<T, E extends string>(schema: Schema.Schema<T...
  class User (line 35) | class User extends Schema.Class<User>('User')({
  type DemoContainerProps (line 49) | type DemoContainerProps = React.ComponentProps<'section'> & {
  function DemoContainer (line 53) | function DemoContainer({
  function EffectSchemaDemo (line 74) | function EffectSchemaDemo() {

FILE: packages/docs/content/docs/parsers/community/tanstack-table.generator.tsx
  constant NUM_PAGES (line 30) | const NUM_PAGES = 5
  function TanStackTablePagination (line 32) | function TanStackTablePagination() {

FILE: packages/docs/content/docs/parsers/community/zod-codecs.demo.tsx
  function ZodCodecsDemo (line 13) | function ZodCodecsDemo() {

FILE: packages/docs/content/docs/parsers/community/zod-codecs.lib.ts
  function createZodCodecParser (line 4) | function createZodCodecParser<
  function invertCodec (line 56) | function invertCodec<A extends z.ZodType, B extends z.ZodType>(

FILE: packages/docs/content/docs/parsers/community/zod-codecs.skeleton.tsx
  function ZodCodecsDemoSkeleton (line 11) | function ZodCodecsDemoSkeleton({

FILE: packages/docs/content/docs/parsers/community/zod-codecs.source.tsx
  function ZodCodecsSource (line 4) | async function ZodCodecsSource() {

FILE: packages/docs/content/docs/parsers/demos.tsx
  function DemoFallback (line 47) | function DemoFallback() {
  type DemoContainerProps (line 55) | type DemoContainerProps = React.ComponentProps<'section'> & {
  function DemoContainer (line 59) | function DemoContainer({
  function BasicUsageDemo (line 79) | function BasicUsageDemo() {
  function StringParserDemo (line 102) | function StringParserDemo() {
  function IntegerParserDemo (line 124) | function IntegerParserDemo() {
  function FloatParserDemo (line 153) | function FloatParserDemo() {
  function HexParserDemo (line 175) | function HexParserDemo() {
  function IndexParserDemo (line 196) | function IndexParserDemo() {
  function BooleanParserDemo (line 246) | function BooleanParserDemo() {
  function StringLiteralParserDemo (line 276) | function StringLiteralParserDemo() {
  function DateParserDemo (line 320) | function DateParserDemo({
  function DatetimeISOParserDemo (line 374) | function DatetimeISOParserDemo() {
  function DateISOParserDemo (line 384) | function DateISOParserDemo() {
  function DateTimestampParserDemo (line 388) | function DateTimestampParserDemo() {
  function JsonParserDemo (line 404) | function JsonParserDemo() {
  constant STAR (line 440) | const STAR = '★'
  type Rating (line 441) | type Rating = 1 | 2 | 3 | 4 | 5
  method parse (line 444) | parse(queryValue) {
  method serialize (line 451) | serialize(value) {
  function CustomParserDemo (line 456) | function CustomParserDemo() {
  function NativeArrayParserDemo (line 478) | function NativeArrayParserDemo() {
  function CustomMultiParserDemo (line 517) | function CustomMultiParserDemo() {
  type StarButtonProps (line 716) | type StarButtonProps = Omit<React.ComponentProps<typeof Button>, 'value'...
  function StarButton (line 722) | function StarButton({ index, value, setValue, ...props }: StarButtonProp...

FILE: packages/docs/mdx-components.tsx
  type Element (line 13) | type Element = React.JSX.Element
  type ElementClass (line 14) | type ElementClass = React.JSX.ElementClass
  type ElementType (line 15) | type ElementType = React.JSX.ElementType
  type IntrinsicElements (line 16) | type IntrinsicElements = React.JSX.IntrinsicElements
  type MDXProvidedComponents (line 37) | type MDXProvidedComponents = typeof components
  function useMDXComponents (line 40) | function useMDXComponents(): MDXProvidedComponents {

FILE: packages/docs/next.config.mjs
  method rewrites (line 76) | async rewrites() {

FILE: packages/docs/src/app/(llms)/llms-full.txt/route.ts
  function GET (line 7) | async function GET() {

FILE: packages/docs/src/app/(llms)/llms.txt/route.ts
  function GET (line 7) | async function GET() {

FILE: packages/docs/src/app/(llms)/llms/[...slug]/route.tsx
  function GET (line 8) | async function GET(
  function generateStaticParams (line 23) | function generateStaticParams() {

FILE: packages/docs/src/app/(pages)/(confs)/nextjs-conf-25/page.tsx
  function Page (line 74) | function Page() {

FILE: packages/docs/src/app/(pages)/(confs)/react-advanced-25/page.tsx
  function Page (line 74) | function Page() {

FILE: packages/docs/src/app/(pages)/(confs)/react-paris/page.tsx
  function Page (line 86) | function Page() {

FILE: packages/docs/src/app/(pages)/_landing/bundle-size.tsx
  function prettyBytes (line 4) | function prettyBytes(size: number) {
  function BundleSize (line 15) | async function BundleSize() {

FILE: packages/docs/src/app/(pages)/_landing/contributors.tsx
  type Contributor (line 11) | type Contributor = z.infer<typeof contributorSchema>
  function fetchContributors (line 13) | async function fetchContributors(): Promise<Contributor[]> {
  function ContributorsSection (line 106) | async function ContributorsSection() {

FILE: packages/docs/src/app/(pages)/_landing/demo.client.tsx
  function Demo (line 6) | function Demo() {

FILE: packages/docs/src/app/(pages)/_landing/demo.tsx
  function LandingDemo (line 7) | async function LandingDemo() {
  function LookAtTheURL (line 38) | function LookAtTheURL() {

FILE: packages/docs/src/app/(pages)/_landing/dependents.tsx
  type Dependent (line 13) | type Dependent = z.infer<typeof dependentSchema>
  function fetchDependents (line 15) | async function fetchDependents() {
  function DependentsSection (line 24) | function DependentsSection() {
  function SponsoredUsedBy (line 36) | function SponsoredUsedBy() {
  function DependentsLeaderboard (line 166) | async function DependentsLeaderboard() {
  function upscaleGitHubAvatar (line 203) | function upscaleGitHubAvatar(originalURL: string, size: number) {

FILE: packages/docs/src/app/(pages)/_landing/features.tsx
  function FeaturesSection (line 19) | function FeaturesSection(props: React.ComponentProps<'section'>) {
  type FeatureProps (line 127) | type FeatureProps = {
  function Feature (line 134) | function Feature({ title, description, icon, isNew }: FeatureProps) {

FILE: packages/docs/src/app/(pages)/_landing/gha-status.tsx
  function GitHubActionsStatus (line 5) | async function GitHubActionsStatus({
  function getGitHubActionsStatus (line 64) | async function getGitHubActionsStatus() {

FILE: packages/docs/src/app/(pages)/_landing/hero.tsx
  function HeroSection (line 9) | function HeroSection() {

FILE: packages/docs/src/app/(pages)/_landing/page-footer.tsx
  function PageFooter (line 11) | function PageFooter() {

FILE: packages/docs/src/app/(pages)/_landing/quotes/quotes-section.tsx
  function QuotesSection (line 3) | function QuotesSection() {

FILE: packages/docs/src/app/(pages)/_landing/sponsors.tsx
  type Sponsors (line 14) | type Sponsors = z.infer<typeof sponsorSchema>[]
  constant SPONSORS (line 16) | const SPONSORS: Sponsors = [
  function SponsorsSection (line 191) | function SponsorsSection() {
  function InlineSponsorsList (line 321) | function InlineSponsorsList({
  function InlineSponsor (line 347) | function InlineSponsor({ url, img, handle, name }: Sponsors[number]) {
  function AsideSponsors (line 369) | function AsideSponsors() {
  function NextJSWeeklyAsideSponsor (line 398) | function NextJSWeeklyAsideSponsor() {
  function ShadcnStudioAsideSponsor (line 432) | function ShadcnStudioAsideSponsor() {

FILE: packages/docs/src/app/(pages)/_landing/works-with.tsx
  function WorksWith (line 12) | function WorksWith({ className, ...props }: ComponentProps<'div'>) {

FILE: packages/docs/src/app/(pages)/blog/[slug]/_components/author.tsx
  function Author (line 1) | function Author() {

FILE: packages/docs/src/app/(pages)/blog/[slug]/opengraph-image.tsx
  function generateStaticParams (line 12) | async function generateStaticParams(): Promise<{ slug: string }[]> {
  function Image (line 19) | async function Image({ params }: PageProps<'/blog/[slug]'>) {
  function getCustomImage (line 48) | async function getCustomImage(slug: string) {

FILE: packages/docs/src/app/(pages)/blog/[slug]/page.tsx
  function Page (line 20) | async function Page(props: {
  function generateMetadata (line 105) | async function generateMetadata(props: {
  function generateStaticParams (line 131) | async function generateStaticParams(): Promise<{ slug: string }[]> {

FILE: packages/docs/src/app/(pages)/blog/_lib/source.ts
  type BlogPost (line 3) | type BlogPost = ReturnType<typeof blog.getPages>[number]
  function getBlogPosts (line 5) | function getBlogPosts() {

FILE: packages/docs/src/app/(pages)/blog/page.tsx
  function BlogIndexPage (line 36) | function BlogIndexPage() {
  type BlogPostLinkProps (line 70) | type BlogPostLinkProps = ComponentProps<'li'> & {
  function BlogPostLink (line 74) | function BlogPostLink({ post, ...props }: BlogPostLinkProps) {
  function RssFeedLink (line 106) | function RssFeedLink() {

FILE: packages/docs/src/app/(pages)/blog/rss.xml/route.ts
  function GET (line 5) | async function GET() {
  function generateRssXml (line 14) | function generateRssXml() {

FILE: packages/docs/src/app/(pages)/layout.tsx
  function PageLayout (line 4) | function PageLayout({

FILE: packages/docs/src/app/(pages)/page.tsx
  function HomePage (line 21) | function HomePage() {

FILE: packages/docs/src/app/(pages)/stats/_components/downloads.client.tsx
  function EstimatedDot (line 17) | function EstimatedDot(props: any) {
  type DownloadsGraphProps (line 33) | type DownloadsGraphProps = WidgetProps & {
  function DownloadsGraph (line 39) | function DownloadsGraph({

FILE: packages/docs/src/app/(pages)/stats/_components/downloads.tsx
  function NPMStats (line 15) | async function NPMStats() {
  function NPMDownloads (line 52) | async function NPMDownloads() {
  function NPMDownloadsSkeleton (line 169) | function NPMDownloadsSkeleton() {
  type TrendBadgeProps (line 210) | type TrendBadgeProps = {
  function TrendBadge (line 217) | function TrendBadge({ oldValue, newValue, label, estimated }: TrendBadge...

FILE: packages/docs/src/app/(pages)/stats/_components/graph.skeleton.tsx
  function GraphSkeleton (line 4) | function GraphSkeleton({ className }: ComponentProps<'div'>) {

FILE: packages/docs/src/app/(pages)/stats/_components/partial-line.tsx
  function clamp (line 5) | function clamp(value: number, min: number, max: number) {
  function getMonotoneSlopes (line 9) | function getMonotoneSlopes(points: Point[]) {
  function getMonotoneSegmentPoint (line 55) | function getMonotoneSegmentPoint(
  function getMonotoneSegmentLength (line 75) | function getMonotoneSegmentLength(
  function getMonotoneLengths (line 104) | function getMonotoneLengths(points: Point[], slopes: number[]) {
  type UseStrokeDashArrayProps (line 123) | type UseStrokeDashArrayProps = {
  type Point (line 134) | type Point = { x: number; y: number }
  function getDashArray (line 136) | function getDashArray(solidLength: number, dashedLength: number) {
  function useStrokeDashArray (line 150) | function useStrokeDashArray({
  function useDebugPoints (line 175) | function useDebugPoints({
  function DebugOverlay (line 198) | function DebugOverlay({ points, slopes }: DebugPoints) {
  type PartialLineProps (line 232) | type PartialLineProps = LineProps & {
  type DebugPoints (line 244) | type DebugPoints = {
  function PartialLine (line 250) | function PartialLine({
  function PartialLineImpl (line 271) | function PartialLineImpl({

FILE: packages/docs/src/app/(pages)/stats/_components/stars.client.tsx
  type StarsGraphProps (line 16) | type StarsGraphProps = {
  type StarTab (line 22) | type StarTab = (typeof starTabs)[number]
  function StarsGraph (line 24) | function StarsGraph({ data, stargazersTab }: StarsGraphProps) {

FILE: packages/docs/src/app/(pages)/stats/_components/stars.gazers-list.tsx
  type Stargazer (line 5) | type Stargazer = GitHubStarHistory['bins'][number]['stargarzers'][number]
  type StargazersListProps (line 7) | type StargazersListProps = {
  function StargazersList (line 11) | function StargazersList({ stars }: StargazersListProps) {
  type StargazerProps (line 48) | type StargazerProps = {
  function Stargazer (line 52) | function Stargazer({

FILE: packages/docs/src/app/(pages)/stats/_components/stars.tsx
  function StarHistoryGraph (line 9) | async function StarHistoryGraph() {
  function StarHistoryGraphSkeleton (line 17) | function StarHistoryGraphSkeleton() {

FILE: packages/docs/src/app/(pages)/stats/_components/versions.tsx
  type VersionProps (line 20) | type VersionProps = {
  function Versions (line 47) | function Versions({ records, versions }: VersionProps) {

FILE: packages/docs/src/app/(pages)/stats/_components/widget.skeleton.tsx
  function WidgetSkeleton (line 4) | function WidgetSkeleton({ className, ...props }: WidgetProps) {

FILE: packages/docs/src/app/(pages)/stats/_components/widget.tsx
  type WidgetProps (line 4) | type WidgetProps = Omit<ComponentProps<'div'>, 'title'> & {
  function Widget (line 8) | function Widget({ title, children, className, ...props }: WidgetProps) {

FILE: packages/docs/src/app/(pages)/stats/lib/format.ts
  constant LOCALE (line 1) | const LOCALE = 'en-GB'
  function formatDate (line 6) | function formatDate(
  function formatTime (line 22) | function formatTime(date: Date | string | number) {
  function formatNumber (line 32) | function formatNumber(value: number) {
  function formatSEOKeyValues (line 36) | function formatSEOKeyValues(dict: Record<string, string>) {
  function formatStatNumber (line 43) | function formatStatNumber(

FILE: packages/docs/src/app/(pages)/stats/lib/github.ts
  type GitHubStarHistory (line 8) | type GitHubStarHistory = {
  function getStarHistory (line 55) | async function getStarHistory(

FILE: packages/docs/src/app/(pages)/stats/lib/npm.ts
  type Datum (line 10) | type Datum = {
  type MultiDatum (line 16) | type MultiDatum = {
  type NpmPackageStatsData (line 23) | type NpmPackageStatsData = {
  type RangeResponse (line 31) | type RangeResponse = {
  function getLastNDays (line 47) | async function getLastNDays(pkg: string, n: number): Promise<Datum[]> {
  function interpolateZeroDays (line 74) | function interpolateZeroDays(data: Datum[]): Datum[] {
  function getPackageCreationDate (line 136) | async function getPackageCreationDate(pkg: string): Promise<dayjs.Dayjs> {
  function getAllTime (line 152) | async function getAllTime(pkg: string): Promise<number> {
  function fetchNpmPackage (line 177) | async function fetchNpmPackage(
  function get (line 197) | async function get(url: string): Promise<unknown> {
  function groupByWeek (line 207) | function groupByWeek(data: Datum[]): Datum[] {
  function combineStats (line 228) | function combineStats(
  function getIsoWeekday (line 251) | function getIsoWeekday(date: string) {
  function getPartialPreviousWeekDownloads (line 256) | function getPartialPreviousWeekDownloads(data: Datum[]) {

FILE: packages/docs/src/app/(pages)/stats/lib/svg.ts
  type Point (line 4) | type Point = [number, number]
  type CommandFn (line 6) | type CommandFn = (point: Point, index: number, array: Point[]) => string
  constant FLOAT_DECIMALS (line 8) | const FLOAT_DECIMALS = 4
  function svgPath (line 10) | function svgPath(points: Point[], command: CommandFn) {
  function controlPoint (line 34) | function controlPoint(

FILE: packages/docs/src/app/(pages)/stats/lib/versions.ts
  type VersionDatum (line 98) | type VersionDatum = {
  function getVersions (line 104) | async function getVersions(beta: boolean): Promise<VersionDatum[]> {
  function sumVersions (line 167) | function sumVersions(versions: VersionDatum[]) {

FILE: packages/docs/src/app/(pages)/stats/page.tsx
  type StatsPageProps (line 18) | type StatsPageProps = {
  function StatsPage (line 22) | async function StatsPage({ searchParams }: StatsPageProps) {
  type VersionsLoaderProps (line 56) | type VersionsLoaderProps = {
  function VersionsLoader (line 60) | async function VersionsLoader({ searchParams }: VersionsLoaderProps) {

FILE: packages/docs/src/app/(pages)/users/page.tsx
  function UsersPage (line 14) | function UsersPage() {
  function UsersList (line 28) | async function UsersList() {
  type LeaderboardItemProps (line 43) | type LeaderboardItemProps = {
  function LeaderboardItem (line 47) | function LeaderboardItem({ dependent }: LeaderboardItemProps) {

FILE: packages/docs/src/app/api/isr/route.ts
  constant ACCEPTED_TAGS (line 4) | const ACCEPTED_TAGS = [
  function GET (line 11) | async function GET(req: NextRequest) {

FILE: packages/docs/src/app/banners.tsx
  function SideBanner (line 12) | function SideBanner() {
  function NuqsV2AnnouncementTopBanner (line 17) | function NuqsV2AnnouncementTopBanner() {
  function NuqsV2AnnouncementSidebarBanner (line 37) | function NuqsV2AnnouncementSidebarBanner() {
  function ReactParis2025SideBanner (line 53) | function ReactParis2025SideBanner() {
  constant NEXTJS_CONF_2025_TALK_TIME (line 92) | const NEXTJS_CONF_2025_TALK_TIME = new Date('2025-10-22T13:55:00-07:00')
  function NextJSConf2025WideBanner (line 94) | function NextJSConf2025WideBanner({
  function NextJSConf2025SideBanner (line 148) | function NextJSConf2025SideBanner({
  constant REACT_ADVANCED_LONDON_2025_TALK_TIME (line 257) | const REACT_ADVANCED_LONDON_2025_TALK_TIME = new Date(
  function ReactAdvancedLondon2025WideBanner (line 261) | function ReactAdvancedLondon2025WideBanner({
  function ReactAdvancedLondon2025SideBanner (line 315) | function ReactAdvancedLondon2025SideBanner({
  function ReactAdvancedLondonLogo (line 356) | function ReactAdvancedLondonLogo({

FILE: packages/docs/src/app/docs/[[...slug]]/page.tsx
  function Page (line 23) | async function Page(props: PageProps<'/docs/[[...slug]]'>) {
  function generateStaticParams (line 58) | async function generateStaticParams() {
  function generateMetadata (line 67) | async function generateMetadata(
  function getSocialImages (line 83) | async function getSocialImages(

FILE: packages/docs/src/app/docs/layout.tsx
  function RootDocsLayout (line 8) | function RootDocsLayout({ children }: { children: ReactNode }) {

FILE: packages/docs/src/app/global-error.tsx
  function GlobalError (line 7) | function GlobalError({ error }: { error: unknown }) {

FILE: packages/docs/src/app/layout.tsx
  function Layout (line 51) | function Layout({ children }: { children: ReactNode }) {

FILE: packages/docs/src/app/not-found.tsx
  function NotFoundPage (line 4) | function NotFoundPage() {
  function NotFoundComponent (line 21) | function NotFoundComponent() {

FILE: packages/docs/src/app/playground/(demos)/_components/source-on-github.tsx
  type SourceOnGitHubProps (line 6) | type SourceOnGitHubProps = {
  function SourceOnGitHub (line 10) | async function SourceOnGitHub({ path }: SourceOnGitHubProps) {
  function readSourceCode (line 40) | function readSourceCode(demoPath: string) {

FILE: packages/docs/src/app/playground/(demos)/basic-counter/client.tsx
  function BasicCounterDemoPage (line 7) | function BasicCounterDemoPage() {

FILE: packages/docs/src/app/playground/(demos)/basic-counter/page.tsx
  function BasicCounterDemoPage (line 9) | function BasicCounterDemoPage() {

FILE: packages/docs/src/app/playground/(demos)/batching/client.tsx
  function BuilderPatternDemoPage (line 8) | function BuilderPatternDemoPage() {

FILE: packages/docs/src/app/playground/(demos)/batching/page.tsx
  function BuilderPatternDemoPage (line 9) | function BuilderPatternDemoPage() {

FILE: packages/docs/src/app/playground/(demos)/demos.ts
  type DemoMetadata (line 3) | type DemoMetadata = {
  function getMetadata (line 33) | function getMetadata(path: keyof typeof demos): DemoMetadata {
  function getPlaygroundTree (line 39) | function getPlaygroundTree(): PageTree.Root {

FILE: packages/docs/src/app/playground/(demos)/hex-colors/client.tsx
  method parse (line 6) | parse(query) {
  method serialize (line 16) | serialize({ r, g, b }) {
  function HexColorsDemo (line 25) | function HexColorsDemo() {
  type ColorSliderProps (line 94) | type ColorSliderProps = {

FILE: packages/docs/src/app/playground/(demos)/hex-colors/page.tsx
  function HexColorsDemoPage (line 9) | function HexColorsDemoPage() {

FILE: packages/docs/src/app/playground/(demos)/layout.tsx
  function PlaygroundDemoLayout (line 5) | function PlaygroundDemoLayout({

FILE: packages/docs/src/app/playground/(demos)/pagination/api.ts
  type Product (line 20) | type Product = (typeof productDatabase)[number]
  function fetchProducts (line 22) | async function fetchProducts(

FILE: packages/docs/src/app/playground/(demos)/pagination/page.tsx
  type PageProps (line 16) | type PageProps = {
  type PaginatedProps (line 20) | type PaginatedProps = {
  function PaginationDemoPage (line 24) | async function PaginationDemoPage({ searchParams }: PageProps) {
  function PaginationRenderer (line 50) | async function PaginationRenderer({ pagination }: PaginatedProps) {
  function ProductSection (line 75) | async function ProductSection({ pagination }: PaginatedProps) {

FILE: packages/docs/src/app/playground/(demos)/pagination/pagination-controls.client.tsx
  type PaginationControlsProps (line 15) | type PaginationControlsProps = {
  function ClientPaginationControls (line 21) | function ClientPaginationControls({

FILE: packages/docs/src/app/playground/(demos)/pagination/pagination-controls.server.tsx
  type PaginationControlsProps (line 12) | type PaginationControlsProps = {
  function ServerPaginationControls (line 18) | async function ServerPaginationControls({

FILE: packages/docs/src/app/playground/(demos)/pagination/product.tsx
  type ProductViewProps (line 3) | type ProductViewProps = React.ComponentProps<'div'> & {
  function ProductView (line 7) | function ProductView({ product, ...props }: ProductViewProps) {

FILE: packages/docs/src/app/playground/(demos)/pagination/rendering-controls.tsx
  function RenderingControls (line 12) | function RenderingControls() {

FILE: packages/docs/src/app/playground/(demos)/pagination/search-params.ts
  type RenderingOptions (line 12) | type RenderingOptions = (typeof renderingOptions)[number]
  type PaginationSearchParams (line 19) | type PaginationSearchParams = inferParserType<typeof searchParams>

FILE: packages/docs/src/app/playground/(demos)/tic-tac-toe/client.tsx
  type Cell (line 8) | type Cell = ' ' | 'x' | 'o'
  type Board (line 9) | type Board = Cell[][]
  type GameStatus (line 10) | type GameStatus = 'x-turn' | 'o-turn' | 'x-wins' | 'o-wins' | 'draw'
  type GameState (line 11) | type GameState = {
  method parse (line 28) | parse(query) {
  method serialize (line 52) | serialize(state) {
  function useGameEngine (line 60) | function useGameEngine() {
  function computeGameStatus (line 86) | function computeGameStatus(board: Board): GameStatus {
  function Board (line 120) | function Board() {
  function Status (line 159) | function Status() {
  function Client (line 171) | function Client() {

FILE: packages/docs/src/app/playground/(demos)/tic-tac-toe/page.tsx
  function Page (line 9) | function Page() {

FILE: packages/docs/src/app/playground/_demos/builder-pattern/page.tsx
  function BuilderPatternDemoPage (line 5) | function BuilderPatternDemoPage() {

FILE: packages/docs/src/app/playground/_demos/compound-parsers/page.tsx
  function CompoundParsersDemo (line 7) | function CompoundParsersDemo() {

FILE: packages/docs/src/app/playground/_demos/crosslink/page.tsx
  function CrosslinkDemoPage (line 8) | function CrosslinkDemoPage() {

FILE: packages/docs/src/app/playground/_demos/custom-parser/page.tsx
  type SortingState (line 5) | type SortingState = Record<string, 'asc' | 'desc'>
  method parse (line 8) | parse(value) {
  method serialize (line 19) | serialize(value: SortingState) {
  function BasicCounterDemoPage (line 26) | function BasicCounterDemoPage() {

FILE: packages/docs/src/app/playground/_demos/parsers/page.tsx
  function BasicCounterDemoPage (line 16) | function BasicCounterDemoPage() {

FILE: packages/docs/src/app/playground/_demos/pretty-urls/page.tsx
  function PrettyURLsDemoPage (line 18) | function PrettyURLsDemoPage() {

FILE: packages/docs/src/app/playground/_demos/repro-359/page.tsx
  type TargetComponent (line 24) | enum TargetComponent {
  function Home (line 29) | function Home() {

FILE: packages/docs/src/app/playground/_demos/repro-376/page.tsx
  function ReproPage (line 5) | function ReproPage() {

FILE: packages/docs/src/app/playground/_demos/repro-907/page.tsx
  function Home (line 8) | function Home() {

FILE: packages/docs/src/app/playground/_demos/server-side-parsing/client.tsx
  type Props (line 6) | type Props = {
  function ServerSideParsingDemoClient (line 11) | function ServerSideParsingDemoClient({

FILE: packages/docs/src/app/playground/_demos/server-side-parsing/page.tsx
  type PageProps (line 5) | type PageProps = {
  function ServerSideParsingDemo (line 11) | function ServerSideParsingDemo({ searchParams }: PageProps) {

FILE: packages/docs/src/app/playground/_demos/throttling/client.tsx
  function Client (line 10) | function Client() {

FILE: packages/docs/src/app/playground/_demos/throttling/page.tsx
  type PageParams (line 6) | type PageParams = {
  function ThottlingDemoPage (line 13) | async function ThottlingDemoPage({ searchParams }: PageParams) {

FILE: packages/docs/src/app/playground/debug-control.tsx
  function DebugControl (line 5) | function DebugControl() {

FILE: packages/docs/src/app/playground/layout.tsx
  function PlaygroundLayout (line 15) | function PlaygroundLayout({

FILE: packages/docs/src/app/playground/page.tsx
  function PlaygroundIndexPage (line 15) | function PlaygroundIndexPage() {

FILE: packages/docs/src/app/registry/[name]/author.tsx
  function Author (line 3) | function Author({ author }: { author: string }) {

FILE: packages/docs/src/app/registry/[name]/opengraph-image.tsx
  function generateStaticParams (line 9) | async function generateStaticParams(): Promise<{ name: string }[]> {
  function Image (line 18) | async function Image({ params }: PageProps<'/registry/[name]'>) {

FILE: packages/docs/src/app/registry/[name]/page.tsx
  function Page (line 26) | async function Page({ params }: PageProps<'/registry/[name]'>) {
  function generateStaticParams (line 96) | async function generateStaticParams() {
  function generateMetadata (line 104) | async function generateMetadata({
  function Installation (line 121) | function Installation({
  function RegistryBuiltFile (line 142) | function RegistryBuiltFile({

FILE: packages/docs/src/app/registry/layout.tsx
  function RegistryLayout (line 23) | async function RegistryLayout({

FILE: packages/docs/src/app/registry/page.tsx
  function Page (line 18) | function Page() {
  function RssFeedLink (line 87) | function RssFeedLink() {

FILE: packages/docs/src/app/registry/rss.xml/route.ts
  function GET (line 7) | async function GET() {
  function generateRssXml (line 16) | async function generateRssXml() {

FILE: packages/docs/src/app/robots.ts
  function robots (line 4) | function robots(): MetadataRoute.Robots {

FILE: packages/docs/src/app/sitemap.ts
  type SitemapEntry (line 10) | type SitemapEntry = MetadataRoute.Sitemap[number]
  function sitemap (line 34) | async function sitemap(): Promise<MetadataRoute.Sitemap> {

FILE: packages/docs/src/app/source.ts
  method file (line 15) | file(node, filePath): Item {
  type Page (line 43) | type Page = InferPageType<typeof source>

FILE: packages/docs/src/components/47ng.tsx
  type Logo47ngProps (line 10) | type Logo47ngProps = React.ComponentProps<'svg'> & {
  function Logo47ng (line 15) | function Logo47ng({

FILE: packages/docs/src/components/ai/page-actions.tsx
  type MarkdownButtonsProps (line 26) | type MarkdownButtonsProps = {
  function CopyAsMarkdownButton (line 30) | function CopyAsMarkdownButton({
  function CopyMarkdownUrlButton (line 75) | function CopyMarkdownUrlButton({ markdownUrl }: MarkdownButtonsProps) {
  function ViewOptions (line 124) | function ViewOptions({

FILE: packages/docs/src/components/audience.tsx
  type AudienceProps (line 3) | type AudienceProps = {
  function HumanContent (line 11) | function HumanContent({ children }: AudienceProps) {
  function LLMContent (line 19) | function LLMContent(_props: AudienceProps) {

FILE: packages/docs/src/components/code-block-defs.ts
  type CodeBlockProps (line 6) | type CodeBlockProps = Omit<FumaDocsCodeBlockProps, 'children'> & {

FILE: packages/docs/src/components/code-block-highlighter.skeleton.ts
  function renderCodeSkeleton (line 1) | function renderCodeSkeleton(code: string) {

FILE: packages/docs/src/components/code-block-highlighter.ts
  function highlight (line 9) | async function highlight(code: string, lang: BundledLanguage) {
  function renderCodeSkeleton (line 24) | function renderCodeSkeleton(code: string) {

FILE: packages/docs/src/components/code-block.client.tsx
  function CodeBlock (line 15) | function CodeBlock({

FILE: packages/docs/src/components/code-block.tsx
  function CodeBlock (line 8) | async function CodeBlock({

FILE: packages/docs/src/components/countdown.tsx
  type CountdownProps (line 7) | type CountdownProps = ComponentProps<'div'> & {
  function Countdown (line 12) | function Countdown({

FILE: packages/docs/src/components/favicon.tsx
  function Favicon (line 1) | function Favicon() {

FILE: packages/docs/src/components/feature-support-matrix.tsx
  type FeatureSupportMatrixProps (line 11) | type FeatureSupportMatrixProps = {
  type Support (line 19) | type Support = {
  function FeatureSupportMatrix (line 24) | function FeatureSupportMatrix({
  function dedupeFrameworks (line 149) | function dedupeFrameworks(frameworks: readonly Frameworks[]) {
  function resolveFrameworks (line 160) | function resolveFrameworks(

FILE: packages/docs/src/components/frameworks.client.tsx
  function NextJS (line 10) | function NextJS({ className, ...props }: IconProps) {

FILE: packages/docs/src/components/frameworks.tsx
  constant FRAMEWORKS (line 5) | const FRAMEWORKS = [
  type Frameworks (line 16) | type Frameworks = (typeof FRAMEWORKS)[number]
  type IconProps (line 17) | type IconProps = ComponentProps<'svg'> & ComponentProps<'img'> & {}
  constant FRAMEWORK_ICONS (line 19) | const FRAMEWORK_ICONS: Record<
  function Vite (line 33) | function Vite({ className, ...props }: IconProps) {
  function ReactSPA (line 80) | function ReactSPA({ className, ...props }: IconProps) {
  function Vitest (line 107) | function Vitest({ className, ...props }: IconProps) {
  function ReactRouter (line 136) | function ReactRouter({ className, ...props }: IconProps) {
  function ReactRouterV7 (line 169) | function ReactRouterV7({ className, ...props }: IconProps) {
  function Remix (line 193) | function Remix({ className, ...props }: IconProps) {
  function TanStackRouter (line 213) | function TanStackRouter({ className, ...props }: IconProps) {

FILE: packages/docs/src/components/github-profile.tsx
  type GitHubProfileProps (line 1) | type GitHubProfileProps = {
  function GitHubProfile (line 7) | function GitHubProfile({

FILE: packages/docs/src/components/kibo-ui/contribution-graph/index.tsx
  type Activity (line 26) | type Activity = {
  type Week (line 32) | type Week = Array<Activity | undefined>;
  type Labels (line 34) | type Labels = {
  type MonthLabel (line 44) | type MonthLabel = {
  constant DEFAULT_MONTH_LABELS (line 49) | const DEFAULT_MONTH_LABELS = [
  constant DEFAULT_LABELS (line 64) | const DEFAULT_LABELS: Labels = {
  type ContributionGraphContextType (line 74) | type ContributionGraphContextType = {
  type ContributionGraphProps (line 225) | type ContributionGraphProps = HTMLAttributes<HTMLDivElement> & {
  type ContributionGraphBlockProps (line 306) | type ContributionGraphBlockProps = HTMLAttributes<SVGRectElement> & {
  type ContributionGraphCalendarProps (line 352) | type ContributionGraphCalendarProps = Omit<
  type ContributionGraphFooterProps (line 422) | type ContributionGraphFooterProps = HTMLAttributes<HTMLDivElement>;
  type ContributionGraphTotalCountProps (line 437) | type ContributionGraphTotalCountProps = Omit<
  type ContributionGraphLegendProps (line 466) | type ContributionGraphLegendProps = Omit<

FILE: packages/docs/src/components/link-tree.tsx
  type LinkTreeItemProps (line 6) | type LinkTreeItemProps = {
  function LinkTreeItem (line 13) | function LinkTreeItem({ href, icon, label, detail }: LinkTreeItemProps) {
  type LinkTreeProps (line 42) | type LinkTreeProps = {
  function LinkTree (line 46) | function LinkTree({ items }: LinkTreeProps) {

FILE: packages/docs/src/components/logo.tsx
  function NuqsWordmark (line 3) | function NuqsWordmark({ className }: React.ComponentProps<'img'>) {

FILE: packages/docs/src/components/og-image.tsx
  type OpengraphImageProps (line 13) | type OpengraphImageProps = {
  function generateOpengraphImage (line 19) | async function generateOpengraphImage({
  function getFont (line 151) | function getFont(weight: string) {
  function loadResources (line 157) | async function loadResources() {
  function getFontSize (line 186) | function getFontSize(text: string) {
  function Logo (line 193) | function Logo(props: ComponentProps<'svg'>) {

FILE: packages/docs/src/components/query-spy.tsx
  function QuerySpy (line 6) | function QuerySpy(props: Omit<QuerystringProps, 'value'>) {

FILE: packages/docs/src/components/querystring.tsx
  type QuerystringProps (line 4) | type QuerystringProps = React.ComponentProps<'pre'> & {
  function Querystring (line 10) | function Querystring({
  function QuerystringSkeleton (line 45) | function QuerystringSkeleton({
  function filterQueryKeys (line 65) | function filterQueryKeys(query: string | URLSearchParams, keys?: string[...

FILE: packages/docs/src/components/quote.tsx
  type AvatarX (line 6) | type AvatarX = {
  type AvatarGitHub (line 10) | type AvatarGitHub = {
  type AvatarOther (line 14) | type AvatarOther = {
  type Avatar (line 18) | type Avatar = AvatarX | AvatarGitHub | AvatarOther
  function getAvatarUrl (line 20) | function getAvatarUrl(avatar: Avatar) {
  type QuoteProps (line 31) | type QuoteProps = {
  function Quote (line 40) | function Quote({ text, author, url }: QuoteProps) {

FILE: packages/docs/src/components/react-paris.tsx
  function ReactParisLogo (line 3) | function ReactParisLogo(props: ComponentProps<'svg'>) {

FILE: packages/docs/src/components/release-contribution-graph.client.tsx
  type ReleaseContributionGraphClientProps (line 21) | type ReleaseContributionGraphClientProps = {
  function ReleaseContributionGraphClient (line 28) | function ReleaseContributionGraphClient({

FILE: packages/docs/src/components/release-contribution-graph.tsx
  function ReleaseContributionGraphSkeleton (line 6) | function ReleaseContributionGraphSkeleton() {
  function ReleaseContributionGraph (line 18) | function ReleaseContributionGraph({
  type GitHubRelease (line 39) | type GitHubRelease = z.infer<typeof gitHubReleaseSchema>
  function fetchGitHubReleases (line 41) | async function fetchGitHubReleases(): Promise<GitHubRelease[]> {
  function isBetaVersion (line 81) | function isBetaVersion(tag: string): boolean {
  type ReleaseDay (line 85) | type ReleaseDay = {
  type ReleasesByDate (line 92) | type ReleasesByDate = Record<string, string[]>
  type ProcessedReleases (line 94) | type ProcessedReleases = {
  function processReleases (line 99) | function processReleases(
  type ReleaseContributionGraphProps (line 167) | type ReleaseContributionGraphProps = {
  function ReleaseContributionGraphLoader (line 171) | async function ReleaseContributionGraphLoader({

FILE: packages/docs/src/components/responsive-helpers.tsx
  function ResponsiveHelper (line 3) | function ResponsiveHelper() {
  function ContainerQueryHelper (line 28) | function ContainerQueryHelper() {

FILE: packages/docs/src/components/shared-layout.tsx
  function getSharedLayoutProps (line 4) | function getSharedLayoutProps(): BaseLayoutProps {

FILE: packages/docs/src/components/sidebar-footer.tsx
  function SidebarFooter (line 5) | function SidebarFooter() {
  function getLatestVersion (line 24) | async function getLatestVersion() {

FILE: packages/docs/src/components/typography.tsx
  function H1 (line 6) | function H1({ children, className, ...props }: ComponentProps<'h1'>) {
  function H2 (line 36) | function H2({ children, className, ...props }: ComponentProps<'h2'>) {

FILE: packages/docs/src/components/ui/badge.tsx
  type BadgeProps (line 26) | interface BadgeProps
  function Badge (line 30) | function Badge({ className, variant, ...props }: BadgeProps) {

FILE: packages/docs/src/components/ui/button.tsx
  type ButtonProps (line 36) | interface ButtonProps

FILE: packages/docs/src/components/ui/card.tsx
  function Card (line 5) | function Card({ className, ...props }: React.ComponentProps<'div'>) {
  function CardHeader (line 18) | function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
  function CardTitle (line 31) | function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
  function CardDescription (line 41) | function CardDescription({ className, ...props }: React.ComponentProps<'...
  function CardAction (line 51) | function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
  function CardContent (line 64) | function CardContent({ className, ...props }: React.ComponentProps<'div'...
  function CardFooter (line 74) | function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {

FILE: packages/docs/src/components/ui/chart.tsx
  constant THEMES (line 12) | const THEMES = { light: '', dark: '.dark' } as const
  type ChartConfig (line 14) | type ChartConfig = {
  type ChartContextProps (line 24) | type ChartContextProps = {
  function useChart (line 30) | function useChart() {
  function ChartContainer (line 40) | function ChartContainer({
  function ChartTooltipContent (line 113) | function ChartTooltipContent({
  function ChartLegendContent (line 275) | function ChartLegendContent({
  function getPayloadConfigFromPayload (line 335) | function getPayloadConfigFromPayload(

FILE: packages/docs/src/components/ui/pagination.tsx
  type PaginationButtonProps (line 42) | type PaginationButtonProps = {
  type PaginationLinkProps (line 62) | type PaginationLinkProps = {

FILE: packages/docs/src/components/ui/popover.tsx
  function Popover (line 8) | function Popover({
  function PopoverTrigger (line 14) | function PopoverTrigger({
  function PopoverContent (line 20) | function PopoverContent({
  function PopoverAnchor (line 42) | function PopoverAnchor({

FILE: packages/docs/src/components/ui/pr-line.tsx
  type PullRequestLineProps (line 12) | type PullRequestLineProps = ComponentProps<'li'> & {
  type Status (line 28) | type Status = 'open' | 'closed' | 'merged' | 'draft'
  function PullRequestLine (line 44) | async function PullRequestLine({

FILE: packages/docs/src/components/ui/tabs.tsx
  function Tabs (line 8) | function Tabs({
  function TabsList (line 21) | function TabsList({
  function TabsTrigger (line 37) | function TabsTrigger({
  function TabsContent (line 53) | function TabsContent({

FILE: packages/docs/src/components/ui/tooltip.tsx
  function TooltipProvider (line 8) | function TooltipProvider({
  function Tooltip (line 21) | function Tooltip({
  function TooltipTrigger (line 31) | function TooltipTrigger({
  function TooltipContent (line 37) | function TooltipContent({

FILE: packages/docs/src/instrumentation.ts
  function register (line 9) | async function register() {

FILE: packages/docs/src/lib/get-last-modified.ts
  function getLastModified (line 3) | async function getLastModified(

FILE: packages/docs/src/lib/get-llm-text.ts
  function getLLMText (line 4) | async function getLLMText(page: Page) {

FILE: packages/docs/src/lib/remark-audience.ts
  type JsxNode (line 14) | type JsxNode = MdxJsxFlowElement | MdxJsxTextElement
  function createJsxHandler (line 26) | function createJsxHandler(isFlow: boolean) {
  function remarkAudience (line 61) | function remarkAudience(this: Processor): Transformer<Root, Root> {

FILE: packages/docs/src/lib/typed-links.ts
  function createTypedLink (line 8) | function createTypedLink<Parsers extends ParserMap>(

FILE: packages/docs/src/lib/url.ts
  function getBaseUrl (line 1) | function getBaseUrl() {

FILE: packages/docs/src/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: packages/docs/src/registry/assemble.ts
  function loadItems (line 23) | async function loadItems() {
  function loadItem (line 34) | async function loadItem(filePath: string) {
  function hydrateItem (line 41) | async function hydrateItem(item: RegistrySourceItem) {
  function hash (line 68) | function hash(...contents: string[]) {
  function main (line 76) | async function main() {

FILE: packages/docs/src/registry/read.ts
  function readRegistry (line 11) | async function readRegistry() {
  function readRegistryItem (line 21) | async function readRegistryItem(name: string) {
  function readUsage (line 34) | async function readUsage(name: string) {
  function categorizeRegistryItems (line 43) | function categorizeRegistryItems(registry: Registry) {

FILE: packages/docs/src/registry/schemas.ts
  type ItemCategory (line 9) | type ItemCategory = (typeof itemCategories)[number]
  type RegistrySourceFile (line 24) | type RegistrySourceFile = z.infer<typeof registrySourceFileSchema>
  type RegistrySourceItem (line 31) | type RegistrySourceItem = z.infer<typeof registrySourceItemSchema>
  type Registry (line 37) | type Registry = z.infer<typeof registrySchema>
  type RegistryBuiltFile (line 47) | type RegistryBuiltFile = z.infer<typeof registryBuiltFileSchema>
  type RegistryBuiltItem (line 52) | type RegistryBuiltItem = z.infer<typeof registryBuiltItemSchema>

FILE: packages/e2e/next/scripts/cache-components-codemod.ts
  function grepFilesWithDynamicExport (line 5) | function grepFilesWithDynamicExport(dir: string): Promise<string[]> {
  function commentDynamicExportInFile (line 30) | async function commentDynamicExportInFile(filePath: string) {
  function main (line 46) | async function main() {

FILE: packages/e2e/next/specs/multitenant.spec.ts
  type Config (line 10) | type Config = {
  function testMultitenant (line 16) | function testMultitenant(config: Config) {

FILE: packages/e2e/next/specs/push.spec.ts
  function runPushTest (line 4) | async function runPushTest(page: Page) {

FILE: packages/e2e/next/specs/repros.spec.ts
  function runTest (line 70) | async function runTest(page: Page, sectionToTry: string) {

FILE: packages/e2e/next/specs/routing-tour.spec.ts
  function waitForHydration (line 4) | async function waitForHydration(page: Page) {
  function clickNext (line 9) | function clickNext(page: Page) {
  function withId (line 17) | function withId(page: Page, id: string) {

FILE: packages/e2e/next/specs/useQueryState.spec.ts
  function runTest (line 4) | async function runTest(page: Page, pathname: string) {

FILE: packages/e2e/next/specs/useQueryStates.spec.ts
  function runTest (line 4) | async function runTest(page: Page) {

FILE: packages/e2e/next/src/app/api/app/loader/route.ts
  function GET (line 8) | async function GET(request: Request) {

FILE: packages/e2e/next/src/app/app/(shared)/basic-io/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/basic-io/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/conditional-rendering/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/conditional-rendering/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/debounce/other/page.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/debounce/page.tsx
  type PageProps (line 7) | type PageProps = {
  function Page (line 11) | async function Page({ searchParams }: PageProps) {

FILE: packages/e2e/next/src/app/app/(shared)/dynamic-segments/catch-all/[...segments]/client.tsx
  function ClientSegment (line 7) | function ClientSegment({ children }: { children?: ReactNode }) {

FILE: packages/e2e/next/src/app/app/(shared)/dynamic-segments/catch-all/[...segments]/page.tsx
  type PageProps (line 7) | type PageProps = {
  function DynamicPage (line 16) | async function DynamicPage(props: PageProps) {

FILE: packages/e2e/next/src/app/app/(shared)/dynamic-segments/dynamic/[segment]/client.tsx
  function ClientSegment (line 7) | function ClientSegment({ children }: { children?: ReactNode }) {

FILE: packages/e2e/next/src/app/app/(shared)/dynamic-segments/dynamic/[segment]/page.tsx
  type PageProps (line 7) | type PageProps = {
  function DynamicPage (line 16) | async function DynamicPage(props: PageProps) {

FILE: packages/e2e/next/src/app/app/(shared)/dynamic-segments/optional-catch-all/[[...segments]]/client.tsx
  function ClientSegment (line 7) | function ClientSegment({ children }: { children?: ReactNode }) {

FILE: packages/e2e/next/src/app/app/(shared)/dynamic-segments/optional-catch-all/[[...segments]]/page.tsx
  type PageProps (line 7) | type PageProps = {
  function DynamicPage (line 16) | async function DynamicPage(props: PageProps) {

FILE: packages/e2e/next/src/app/app/(shared)/flush-after-navigate/useQueryState/end/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/flush-after-navigate/useQueryState/start/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/flush-after-navigate/useQueryStates/end/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/flush-after-navigate/useQueryStates/start/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/form/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/form/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/hash-preservation/dynamic/[route]/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/hash-preservation/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/history-sync/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/json/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/life-and-death/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/linking/useQueryState/other/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/linking/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/linking/useQueryStates/other/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/linking/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/native-array/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/popstate-queue-reset/page.tsx
  function PopstateQueueResetWrapper (line 7) | function PopstateQueueResetWrapper() {
  function Page (line 16) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/pretty-urls/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/push/useQueryState/dynamic/[route]/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/push/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/push/useQueryStates/dynamic/[route]/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/push/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/rate-limits/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/referential-stability/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/referential-stability/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/render-count/[hook]/[shallow]/[history]/[startTransition]/page.tsx
  type PageProps (line 12) | type PageProps = {
  function Page (line 17) | async function Page({
  function generateStaticParams (line 38) | async function generateStaticParams() {

FILE: packages/e2e/next/src/app/app/(shared)/repro-1365/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/repro-359/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/repro-982/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/routing/useQueryState/other/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/routing/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/routing/useQueryStates/other/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/routing/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/scroll/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/(shared)/shallow/useQueryState/page.tsx
  type PageProps (line 10) | type PageProps = {
  function Page (line 25) | async function Page({ searchParams }: PageProps) {

FILE: packages/e2e/next/src/app/app/(shared)/shallow/useQueryStates/page.tsx
  type PageProps (line 10) | type PageProps = {
  function Page (line 25) | async function Page({ searchParams }: PageProps) {

FILE: packages/e2e/next/src/app/app/(shared)/stitching/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/agnostic/basic-io/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/agnostic/layout.tsx
  function RouterAgnosticLayout (line 4) | function RouterAgnosticLayout({

FILE: packages/e2e/next/src/app/app/cache/all.tsx
  function All (line 3) | function All() {

FILE: packages/e2e/next/src/app/app/cache/get.tsx
  function Get (line 3) | function Get() {

FILE: packages/e2e/next/src/app/app/cache/layout.tsx
  function Layout (line 4) | function Layout({ children }: { children: React.ReactNode }) {

FILE: packages/e2e/next/src/app/app/cache/page.tsx
  type Props (line 8) | type Props = {
  function Page (line 12) | async function Page({ searchParams }: Props) {
  function generateMetadata (line 35) | async function generateMetadata({ searchParams }: Props) {

FILE: packages/e2e/next/src/app/app/cache/set.tsx
  function Set (line 6) | function Set() {

FILE: packages/e2e/next/src/app/app/deferred/page.tsx
  function Page (line 6) | function Page() {
  function DeferredForm (line 15) | function DeferredForm() {
  function InternalState (line 40) | function InternalState() {
  function passThru (line 56) | function passThru<T>(x: T): T {

FILE: packages/e2e/next/src/app/app/loader/page.tsx
  type PageProps (line 4) | type PageProps = {
  function Page (line 8) | async function Page({ searchParams }: PageProps) {

FILE: packages/e2e/next/src/app/app/multitenant/[tenant]/client-tenant.tsx
  function TenantClient (line 5) | function TenantClient() {

FILE: packages/e2e/next/src/app/app/multitenant/[tenant]/page.tsx
  type PageProps (line 11) | type PageProps = {
  function TenantPage (line 27) | async function TenantPage({ params, searchParams }: PageProps) {

FILE: packages/e2e/next/src/app/app/persist-across-navigation/a/page.tsx
  function Page (line 6) | function Page() {

FILE: packages/e2e/next/src/app/app/persist-across-navigation/b/page.tsx
  function Page (line 6) | function Page() {

FILE: packages/e2e/next/src/app/app/persist-across-navigation/client.tsx
  type Page (line 9) | type Page = 'a' | 'b'
  type ClientProps (line 11) | type ClientProps = {
  function Client (line 22) | function Client({ page, target }: ClientProps) {

FILE: packages/e2e/next/src/app/app/push/client.tsx
  function Client (line 6) | function Client() {

FILE: packages/e2e/next/src/app/app/push/page.tsx
  function Page (line 6) | async function Page({

FILE: packages/e2e/next/src/app/app/referential-equality/page.tsx
  function Page (line 7) | function Page() {
  type Value (line 16) | type Value = typeof defaultValue
  function increment (line 18) | function increment(value: Value): Value {
  function Client (line 29) | function Client() {

FILE: packages/e2e/next/src/app/app/remapped-keys/page.tsx
  function Page (line 11) | function Page() {
  function Client (line 19) | function Client() {

FILE: packages/e2e/next/src/app/app/repro-1099/useQueryState/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/repro-1099/useQueryStates/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/repro-1293/a/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/repro-1293/b/page.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/app/app/repro-388/page.tsx
  function Page (line 9) | function Page() {
  function Client (line 17) | function Client() {

FILE: packages/e2e/next/src/app/app/repro-498/page.tsx
  function Page (line 6) | function Page() {
  function Client (line 19) | function Client() {

FILE: packages/e2e/next/src/app/app/repro-542/a/page.tsx
  function Page (line 6) | function Page() {

FILE: packages/e2e/next/src/app/app/repro-542/b/page.tsx
  function Page (line 6) | function Page() {

FILE: packages/e2e/next/src/app/app/repro-542/client.tsx
  type ClientProps (line 7) | type ClientProps = {
  type Ref (line 12) | type Ref = {
  function Client (line 17) | function Client({ page, linkTo }: ClientProps) {

FILE: packages/e2e/next/src/app/app/repro-630/page.tsx
  function Page (line 6) | function Page() {
  type ClientProps (line 17) | type ClientProps = {
  function Client (line 21) | function Client({ id }: ClientProps) {
  function Clients (line 58) | function Clients({ id }: ClientProps) {

FILE: packages/e2e/next/src/app/app/repro-758/page.tsx
  function Page (line 6) | function Page() {
  function Client (line 14) | function Client() {

FILE: packages/e2e/next/src/app/app/repro-760/page.tsx
  function Page (line 6) | function Page() {
  function DynamicUseQueryState (line 15) | function DynamicUseQueryState() {
  function DynamicUseQueryStates (line 28) | function DynamicUseQueryStates() {

FILE: packages/e2e/next/src/app/app/repro-774/page.tsx
  function Home (line 7) | function Home() {
  function Client (line 27) | function Client() {

FILE: packages/e2e/next/src/app/app/rewrites/destination/client.tsx
  function RewriteDestinationClient (line 6) | function RewriteDestinationClient() {

FILE: packages/e2e/next/src/app/app/rewrites/destination/page.tsx
  function RewriteDestinationPage (line 6) | async function RewriteDestinationPage({

FILE: packages/e2e/next/src/app/app/routing-tour/_components/view.tsx
  type RoutingTourViewProps (line 7) | type RoutingTourViewProps = {

FILE: packages/e2e/next/src/app/app/routing-tour/a/page.tsx
  function PageA (line 4) | function PageA() {

FILE: packages/e2e/next/src/app/app/routing-tour/b/page.tsx
  function PageB (line 4) | function PageB() {

FILE: packages/e2e/next/src/app/app/routing-tour/c/page.tsx
  function Page (line 6) | function Page() {
  function PageC (line 14) | function PageC() {

FILE: packages/e2e/next/src/app/app/routing-tour/d/page.tsx
  function Page (line 6) | function Page() {
  function PageD (line 14) | function PageD() {

FILE: packages/e2e/next/src/app/app/routing-tour/start/client/page.tsx
  function Page (line 6) | function Page() {
  function ClientStartPage (line 14) | function ClientStartPage() {

FILE: packages/e2e/next/src/app/app/routing-tour/start/server/page.tsx
  function ServerStartPage (line 3) | function ServerStartPage() {

FILE: packages/e2e/next/src/app/app/template/page.tsx
  function Page (line 6) | function Page() {
  function Client (line 14) | function Client() {

FILE: packages/e2e/next/src/app/app/transitions/client.tsx
  function Client (line 6) | function Client() {

FILE: packages/e2e/next/src/app/app/transitions/page.tsx
  type PageProps (line 6) | type PageProps = {
  function Page (line 10) | async function Page({ searchParams }: PageProps) {

FILE: packages/e2e/next/src/app/app/useQueryState/page.tsx
  function Page (line 15) | function Page() {
  function IntegrationPage (line 23) | function IntegrationPage() {

FILE: packages/e2e/next/src/app/app/useQueryStates-clear-all/page.tsx
  function Page (line 6) | function Page() {
  function Client (line 14) | function Client() {

FILE: packages/e2e/next/src/app/app/useQueryStates/page.tsx
  function Page (line 14) | function Page() {
  function IntegrationPage (line 22) | function IntegrationPage() {

FILE: packages/e2e/next/src/app/app/useSearchParams/page.tsx
  function Page (line 7) | function Page() {
  function Client (line 15) | function Client() {

FILE: packages/e2e/next/src/app/layout.tsx
  function RootLayout (line 13) | function RootLayout({ children }: { children: ReactNode }) {

FILE: packages/e2e/next/src/app/page.tsx
  function IndexPage (line 3) | function IndexPage() {

FILE: packages/e2e/next/src/app/providers.tsx
  function Providers (line 9) | function Providers({ children }: { children: ReactNode }) {
  function useRouter (line 17) | function useRouter(): Router {

FILE: packages/e2e/next/src/components/pages-ready-wrapper.tsx
  function withPagesReadyWrapper (line 3) | function withPagesReadyWrapper(Component: React.ComponentType) {

FILE: packages/e2e/next/src/middleware.ts
  function proxy (line 7) | async function proxy(req: NextRequest) {

FILE: packages/e2e/next/src/pages/_app.tsx
  function MyApp (line 9) | function MyApp({ Component, pageProps }: AppProps) {
  function useRouter (line 24) | function useRouter(): Router {

FILE: packages/e2e/next/src/pages/api/pages/loader.ts
  function handler (line 4) | function handler(

FILE: packages/e2e/next/src/pages/pages/agnostic/basic-io.tsx
  function Page (line 7) | function Page() {

FILE: packages/e2e/next/src/pages/pages/debounce/index.tsx
  function Page (line 9) | function Page(serverState: DemoSearchParams) {
  function getServerSideProps (line 17) | async function getServerSideProps(ctx: GetServerSidePropsContext) {

FILE: packages/e2e/next/src/pages/pages/debounce/other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/dynamic-segments/catch-all/[...segments].tsx
  type Props (line 6) | type Props = {
  function Page (line 11) | function Page({ serverState, serverSegments }: Props) {
  function getServerSideProps (line 27) | function getServerSideProps(

FILE: packages/e2e/next/src/pages/pages/dynamic-segments/dynamic/[segment].tsx
  type Props (line 6) | type Props = {
  function Page (line 11) | function Page({ serverState, serverSegments }: Props) {
  function getServerSideProps (line 27) | function getServerSideProps(

FILE: packages/e2e/next/src/pages/pages/dynamic-segments/optional-catch-all/[[...segments]].tsx
  type Props (line 6) | type Props = {
  function Page (line 11) | function Page({ serverState, serverSegments }: Props) {
  function getServerSideProps (line 30) | function getServerSideProps(

FILE: packages/e2e/next/src/pages/pages/flush-after-navigate/useQueryState/start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/flush-after-navigate/useQueryStates/start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/linking/useQueryState/index.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/linking/useQueryState/other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/linking/useQueryStates/index.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/linking/useQueryStates/other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/loader.tsx
  type PageProps (line 8) | type PageProps = {
  function Page (line 12) | function Page({ serverValues }: PageProps) {
  function getServerSideProps (line 16) | async function getServerSideProps({ query }: GetServerSidePropsContext) {

FILE: packages/e2e/next/src/pages/pages/middleware.tsx
  function MiddlewarePage (line 1) | function MiddlewarePage() {

FILE: packages/e2e/next/src/pages/pages/multitenant/[tenant].tsx
  type Props (line 7) | type Props = {
  function Page (line 12) | function Page({ serverState, tenant }: Props) {
  function getServerSideProps (line 26) | function getServerSideProps(

FILE: packages/e2e/next/src/pages/pages/popstate-queue-reset/index.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/next/src/pages/pages/push/index.tsx
  function Page (line 5) | function Page({ server }: { server: number }) {

FILE: packages/e2e/next/src/pages/pages/repro-1293/a.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/routing/useQueryState/index.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/routing/useQueryState/other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/routing/useQueryStates/index.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/routing/useQueryStates/other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/next/src/pages/pages/shallow/useQueryState.tsx
  type Props (line 5) | type Props = {
  function Page (line 9) | function Page({ serverState }: Props) {
  function getServerSideProps (line 18) | function getServerSideProps(

FILE: packages/e2e/next/src/pages/pages/shallow/useQueryStates.tsx
  type Props (line 5) | type Props = {
  function Page (line 9) | function Page({ serverState }: Props) {
  function getServerSideProps (line 18) | function getServerSideProps(

FILE: packages/e2e/react-router/v5/src/adapter.ts
  function useNuqsReactRouterV5Adapter (line 10) | function useNuqsReactRouterV5Adapter(): AdapterInterface {

FILE: packages/e2e/react-router/v5/src/layout.tsx
  function Link (line 7) | function Link({ href, ...props }: LinkProps) {
  function RootLayout (line 11) | function RootLayout({ children }: { children: ReactNode }) {
  function useRouter (line 22) | function useRouter(): Router {

FILE: packages/e2e/react-router/v5/src/react-router.tsx
  function ReactRouter (line 53) | function ReactRouter() {

FILE: packages/e2e/react-router/v5/src/routes/fog-of-war._index.tsx
  function FogOfWarStart (line 3) | function FogOfWarStart() {

FILE: packages/e2e/react-router/v5/src/routes/linking.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/linking.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/linking.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/linking.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
  function Page (line 5) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/routing.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/routing.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/routing.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v5/src/routes/routing.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/layout.tsx
  function Link (line 6) | function Link({ href, ...props }: LinkProps) {
  function RootLayout (line 10) | function RootLayout() {
  function useRouter (line 23) | function useRouter(): Router {

FILE: packages/e2e/react-router/v6/src/react-router.tsx
  function load (line 11) | function load(mod: Promise<{ default: any; [otherExports: string]: any }...
  function ReactRouter (line 90) | function ReactRouter() {

FILE: packages/e2e/react-router/v6/src/routes/debounce.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/debounce.tsx
  function loader (line 9) | function loader({ request }: LoaderFunctionArgs) {
  function Page (line 13) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/dynamic-segments.catch-all.$.tsx
  function loader (line 14) | function loader({ request, params }: LoaderFunctionArgs) {
  function Page (line 22) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/dynamic-segments.dynamic.$segment.tsx
  function loader (line 14) | function loader({ request, params }: LoaderFunctionArgs) {
  function Page (line 22) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/flush-after-navigate.useQueryState.start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/flush-after-navigate.useQueryStates.start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/fog-of-war._index.tsx
  function FogOfWarStart (line 3) | function FogOfWarStart() {

FILE: packages/e2e/react-router/v6/src/routes/linking.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/linking.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/linking.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/linking.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/loader.tsx
  function loader (line 4) | function loader({ request }: LoaderFunctionArgs) {
  function Page (line 8) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/popstate-queue-reset.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
  function loader (line 11) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 19) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
  function Page (line 5) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
  function loader (line 5) | function loader() {
  function Page (line 9) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/repro-1293.a.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/repro-1293.b.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/repro-839.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/routing.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/routing.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/routing.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/routing.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/shallow.useQueryState.tsx
  function loader (line 5) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 12) | function Page() {

FILE: packages/e2e/react-router/v6/src/routes/shallow.useQueryStates.tsx
  function loader (line 5) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 12) | function Page() {

FILE: packages/e2e/react-router/v7/app/layout.tsx
  function Link (line 6) | function Link({ href, ...props }: LinkProps) {
  function RootLayout (line 10) | function RootLayout() {
  function useRouter (line 23) | function useRouter(): Router {

FILE: packages/e2e/react-router/v7/app/root.tsx
  function Layout (line 13) | function Layout({ children }: { children: React.ReactNode }) {
  function App (line 31) | function App() {
  function ErrorBoundary (line 39) | function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {

FILE: packages/e2e/react-router/v7/app/routes/debounce.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/debounce.tsx
  function loader (line 7) | function loader({ request }: LoaderFunctionArgs) {
  function Page (line 11) | function Page({

FILE: packages/e2e/react-router/v7/app/routes/dynamic-segments.catch-all.$.tsx
  function loader (line 10) | function loader({ request, params }: LoaderFunctionArgs) {
  function Page (line 18) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/dynamic-segments.dynamic.$segment.tsx
  function loader (line 10) | function loader({ request, params }: LoaderFunctionArgs) {
  function Page (line 18) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/flush-after-navigate.useQueryState.start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/flush-after-navigate.useQueryStates.start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/fog-of-war._index.tsx
  function FogOfWarStart (line 3) | function FogOfWarStart() {

FILE: packages/e2e/react-router/v7/app/routes/linking.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/linking.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/linking.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/linking.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/loader.tsx
  function loader (line 5) | function loader({ request }: LoaderFunctionArgs) {
  function Page (line 9) | function Page({

FILE: packages/e2e/react-router/v7/app/routes/popstate-queue-reset.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
  function loader (line 9) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 17) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
  function Page (line 5) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
  function loader (line 5) | function loader() {
  function Page (line 9) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/repro-1293.a.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/repro-1293.b.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/repro-839.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/routing.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/routing.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/routing.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/routing.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/shallow.useQueryState.tsx
  function loader (line 5) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 12) | function Page() {

FILE: packages/e2e/react-router/v7/app/routes/shallow.useQueryStates.tsx
  function loader (line 5) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 12) | function Page() {

FILE: packages/e2e/react-router/v7/server.mjs
  function run (line 15) | async function run() {

FILE: packages/e2e/react-router/v7/vite.config.ts
  method onwarn (line 10) | onwarn(warning, warn) {

FILE: packages/e2e/react/src/layout.tsx
  function Link (line 6) | function Link({ href, ...props }: LinkProps) {
  function RootLayout (line 10) | function RootLayout({ children }: { children: ReactNode }) {
  function useRouter (line 21) | function useRouter(): Router {

FILE: packages/e2e/react/src/routes.tsx
  function Router (line 66) | function Router() {

FILE: packages/e2e/react/src/routes/linking.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react/src/routes/linking.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react/src/routes/linking.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react/src/routes/linking.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react/src/routes/render-count.tsx
  function Page (line 5) | function Page() {

FILE: packages/e2e/react/src/routes/routing.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react/src/routes/routing.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react/src/routes/routing.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/react/src/routes/routing.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/entry.server.tsx
  constant ABORT_DELAY (line 15) | const ABORT_DELAY = 5_000;
  function handleRequest (line 17) | function handleRequest(
  function handleBotRequest (line 42) | function handleBotRequest(
  function handleBrowserRequest (line 92) | function handleBrowserRequest(

FILE: packages/e2e/remix/app/layout.tsx
  function Link (line 6) | function Link({ href, ...props }: LinkProps) {
  function RootLayout (line 10) | function RootLayout() {
  function useRouter (line 23) | function useRouter(): Router {

FILE: packages/e2e/remix/app/root.tsx
  function Layout (line 5) | function Layout({ children }: { children: React.ReactNode }) {
  function App (line 23) | function App() {

FILE: packages/e2e/remix/app/routes/debounce-other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/debounce.tsx
  function loader (line 10) | function loader({ request }: LoaderFunctionArgs) {
  function Page (line 14) | function Page() {

FILE: packages/e2e/remix/app/routes/dynamic-segments.catch-all.$.tsx
  function loader (line 11) | function loader({ request, params }: LoaderFunctionArgs) {
  function Page (line 19) | function Page() {

FILE: packages/e2e/remix/app/routes/dynamic-segments.dynamic.$segment.tsx
  function loader (line 11) | function loader({ request, params }: LoaderFunctionArgs) {
  function Page (line 19) | function Page() {

FILE: packages/e2e/remix/app/routes/flush-after-navigate.useQueryState.start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/flush-after-navigate.useQueryStates.start.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/fog-of-war._index.tsx
  function FogOfWarStart (line 3) | function FogOfWarStart() {

FILE: packages/e2e/remix/app/routes/linking.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/linking.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/linking.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/linking.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/loader.tsx
  function loader (line 5) | function loader({ request }: LoaderFunctionArgs) {
  function Page (line 9) | function Page() {

FILE: packages/e2e/remix/app/routes/popstate-queue-reset.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/remix/app/routes/render-count.$hook.$shallow.$history.$startTransition.async-loader.tsx
  function loader (line 10) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 18) | function Page() {

FILE: packages/e2e/remix/app/routes/render-count.$hook.$shallow.$history.$startTransition.no-loader.tsx
  function Page (line 5) | function Page() {

FILE: packages/e2e/remix/app/routes/render-count.$hook.$shallow.$history.$startTransition.sync-loader.tsx
  function loader (line 5) | function loader() {
  function Page (line 9) | function Page() {

FILE: packages/e2e/remix/app/routes/repro-1293.a.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/repro-839.tsx
  function Page (line 4) | function Page() {

FILE: packages/e2e/remix/app/routes/routing.useQueryState.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/routing.useQueryState.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/routing.useQueryStates.other.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/routing.useQueryStates.tsx
  function Page (line 3) | function Page() {

FILE: packages/e2e/remix/app/routes/shallow.useQueryState.tsx
  function loader (line 6) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 13) | function Page() {

FILE: packages/e2e/remix/app/routes/shallow.useQueryStates.tsx
  function loader (line 6) | async function loader({ request }: LoaderFunctionArgs) {
  function Page (line 13) | function Page() {

FILE: packages/e2e/remix/vite.config.ts
  method onwarn (line 19) | onwarn(warning, warn) {

FILE: packages/e2e/shared/components/display.tsx
  type DisplayProps (line 3) | type DisplayProps = {
  function Display (line 9) | function Display({

FILE: packages/e2e/shared/components/link.tsx
  type LinkProps (line 3) | type LinkProps = ComponentProps<'a'> & {
  type LinkContextValue (line 9) | type LinkContextValue = {
  function useLink (line 19) | function useLink() {
  function LinkProvider (line 23) | function LinkProvider({

FILE: packages/e2e/shared/components/null-detector.tsx
  type NullDetectorProps (line 3) | type NullDetectorProps = {
  function NullDetector (line 10) | function NullDetector({

FILE: packages/e2e/shared/components/router.tsx
  type RouterOptions (line 3) | type RouterOptions = {
  type Router (line 7) | type Router = {
  type RouterContextValue (line 12) | type RouterContextValue = () => Router
  function useRouter (line 20) | function useRouter() {
  function RouterProvider (line 24) | function RouterProvider({

FILE: packages/e2e/shared/define-test.ts
  type TestConfig (line 3) | type TestConfig = {
  function defineTest (line 27) | function defineTest(

FILE: packages/e2e/shared/playwright.config.ts
  type ConfigurePlaywright (line 7) | type ConfigurePlaywright = {
  function configurePlaywright (line 13) | function configurePlaywright({
  function ensureTrailingSlash (line 58) | function ensureTrailingSlash(path: string) {

FILE: packages/e2e/shared/playwright/agent-reporter.ts
  function stripAnsi (line 11) | function stripAnsi(text: string) {
  function formatDuration (line 15) | function formatDuration(durationMs: number) {
  class AgentReporter (line 26) | class AgentReporter implements Reporter {
    method onBegin (line 32) | onBegin(_config: FullConfig, suite: Suite) {
    method onTestEnd (line 36) | onTestEnd(test: TestCase, result: TestResult) {
    method onError (line 52) | onError(error: TestError) {
    method onEnd (line 65) | onEnd(result: FullResult) {
    method printFailure (line 80) | private printFailure(test: TestCase, result: TestResult) {
    method pushError (line 120) | private pushError(lines: string[], error: TestError) {

FILE: packages/e2e/shared/playwright/expect-url.ts
  type ExpectUrlOptions (line 3) | type ExpectUrlOptions = {
  function expectUrl (line 9) | function expectUrl(
  function expectSearch (line 25) | function expectSearch(page: Page, expected: Record<string, string>) {

FILE: packages/e2e/shared/playwright/log-spy.ts
  type LogSpy (line 4) | type LogSpy = {
  function setupLogSpy (line 9) | function setupLogSpy(page: Page): LogSpy {
  function assertLogCount (line 25) | function assertLogCount(

FILE: packages/e2e/shared/playwright/navigate.ts
  function navigateTo (line 3) | async function navigateTo(page: Page, pathname: string, search = '') {

FILE: packages/e2e/shared/playwright/reporter.ts
  function dim (line 26) | function dim(text: string) {
  function dimYellow (line 30) | function dimYellow(text: string) {
  function stripAnsi (line 34) | function stripAnsi(text: string) {
  function visibleWidth (line 38) | function visibleWidth(text: string) {
  function fitTitleToScreen (line 42) | function fitTitleToScreen(title: string, prefix: string, suffix: string) {
  function formatDuration (line 55) | function formatDuration(durationMs: number) {
  class CompactListReporter (line 66) | class CompactListReporter implements Reporter {
    method onBegin (line 77) | onBegin(config: FullConfig, suite: Suite) {
    method onTestBegin (line 94) | onTestBegin(test: TestCase, _result: TestResult) {
    method onTestEnd (line 109) | onTestEnd(test: TestCase, result: TestResult) {
    method onError (line 159) | onError(error: TestError) {
    method onEnd (line 169) | onEnd(result: FullResult) {
    method formatTitlePath (line 213) | private formatTitlePath(test: TestCase) {
    method updateOrAppendLine (line 227) | private updateOrAppendLine(test: TestCase, line: string) {
    method appendLine (line 243) | private appendLine(line: string) {
    method writeLine (line 247) | private writeLine(line: string) {
    method writeLineUnlocked (line 255) | private writeLineUnlocked(line: string) {
    method writeBlock (line 261) | private writeBlock(lines: string[]) {
    method pushLogLines (line 267) | private pushLogLines(lines: string[], message: string | undefined) {
    method formatResultSuffix (line 274) | private formatResultSuffix(
    method formatRetrySuffix (line 291) | private formatRetrySuffix(test: TestCase, result: TestResult) {
    method withOutputLock (line 298) | private withOutputLock(action: () => void) {
    method updateLine (line 312) | private updateLine(row: number, line: string) {

FILE: packages/e2e/shared/playwright/url-spy.ts
  type UrlSpy (line 3) | type UrlSpy = {
  function setupUrlSpy (line 9) | function setupUrlSpy(page: Page): UrlSpy {

FILE: packages/e2e/shared/shared.spec.ts
  function runSharedTests (line 16) | function runSharedTests(

FILE: packages/e2e/shared/specs/basic-io.tsx
  function UseQueryStateBasicIO (line 6) | function UseQueryStateBasicIO() {
  function UseQueryStatesBasicIO (line 22) | function UseQueryStatesBasicIO() {

FILE: packages/e2e/shared/specs/conditional-rendering.tsx
  function ConditionalRenderer (line 7) | function ConditionalRenderer({ Component }: { Component: FC }) {
  function TestComponentUseQueryState (line 24) | function TestComponentUseQueryState() {
  function TestComponentUseQueryStates (line 37) | function TestComponentUseQueryStates() {
  function ConditionalRenderingUseQueryState (line 57) | function ConditionalRenderingUseQueryState() {
  function ConditionalRenderingUseQueryStates (line 61) | function ConditionalRenderingUseQueryStates() {

FILE: packages/e2e/shared/specs/debounce-client.tsx
  type DebounceProps (line 13) | type DebounceProps = {
  function DebounceClient (line 17) | function DebounceClient({ navigateHref }: DebounceProps) {

FILE: packages/e2e/shared/specs/debounce-server.tsx
  type DebounceServerDisplayProps (line 4) | type DebounceServerDisplayProps = {
  function DebounceServer (line 9) | function DebounceServer({

FILE: packages/e2e/shared/specs/debounce.defs.ts
  type DemoSearchParams (line 27) | type DemoSearchParams = inferParserType<typeof demoSearchParams>

FILE: packages/e2e/shared/specs/debounce.spec.ts
  type TestDebounceConfig (line 6) | type TestDebounceConfig = TestConfig & {
  function testDebounce (line 10) | function testDebounce(config: TestDebounceConfig) {

FILE: packages/e2e/shared/specs/dynamic-segments.spec.ts
  type TestDynamicSegmentsOptions (line 6) | type TestDynamicSegmentsOptions = TestConfig & {
  function testDynamicSegments (line 10) | function testDynamicSegments({

FILE: packages/e2e/shared/specs/dynamic-segments.tsx
  type UrlControlsProps (line 8) | type UrlControlsProps = {
  function UrlControls (line 12) | function UrlControls({ children }: UrlControlsProps) {
  type DisplaySegmentsProps (line 26) | type DisplaySegmentsProps = Pick<DisplayProps, 'environment'> & {
  function DisplaySegments (line 30) | function DisplaySegments({

FILE: packages/e2e/shared/specs/flush-after-navigate.spec.ts
  function expectPathname (line 6) | async function expectPathname(page: Page, pathname: string) {
  function testFlushAfterNavigate (line 10) | function testFlushAfterNavigate(config: TestConfig) {

FILE: packages/e2e/shared/specs/flush-after-navigate.tsx
  function FlushAfterNavigateUseQueryStateStart (line 10) | function FlushAfterNavigateUseQueryStateStart({
  function FlushAfterNavigateUseQueryStatesStart (line 45) | function FlushAfterNavigateUseQueryStatesStart({
  function FlushAfterNavigateEnd (line 80) | function FlushAfterNavigateEnd() {

FILE: packages/e2e/shared/specs/form.tsx
  type FormProps (line 5) | type FormProps = {
  function Form (line 11) | function Form({ defaultValue }: FormProps) {
  function TestFormUseQueryState (line 20) | function TestFormUseQueryState() {
  function TestFormUseQueryStates (line 30) | function TestFormUseQueryStates() {

FILE: packages/e2e/shared/specs/hash-preservation.tsx
  function HashPreservation (line 5) | function HashPreservation() {

FILE: packages/e2e/shared/specs/history-sync.tsx
  function HistorySync (line 6) | function HistorySync() {

FILE: packages/e2e/shared/specs/json.tsx
  type Schema (line 19) | type Schema = inferParserType<typeof schema>
  function Json (line 29) | function Json() {

FILE: packages/e2e/shared/specs/key-isolation.tsx
  type TestComponentProps (line 3) | type TestComponentProps = {
  function KeyIsolationUseQueryState (line 7) | function KeyIsolationUseQueryState() {
  function KeyIsolationUseQueryStates (line 16) | function KeyIsolationUseQueryStates() {
  function TestComponentUseQueryState (line 25) | function TestComponentUseQueryState({ id }: TestComponentProps) {
  function TestComponentUseQueryStates (line 38) | function TestComponentUseQueryStates({ id }: TestComponentProps) {

FILE: packages/e2e/shared/specs/life-and-death.spec.ts
  function assertFilledState (line 65) | async function assertFilledState(page: Page) {
  function assertEmptyState (line 72) | async function assertEmptyState(page: Page) {

FILE: packages/e2e/shared/specs/life-and-death.tsx
  function LifeAndDeath (line 7) | function LifeAndDeath() {
  function LifeAndDeathUseQueryState (line 19) | function LifeAndDeathUseQueryState() {
  function ChildComponentUseQueryState (line 31) | function ChildComponentUseQueryState() {
  function LifeAndDeathUseQueryStates (line 46) | function LifeAndDeathUseQueryStates() {
  function ChildComponentUseQueryStates (line 58) | function ChildComponentUseQueryStates() {

FILE: packages/e2e/shared/specs/linking.tsx
  type Props (line 6) | type Props = {
  function LinkingUseQueryState (line 10) | function LinkingUseQueryState({ path }: Props) {
  function LinkingUseQueryStates (line 21) | function LinkingUseQueryStates({ path }: Props) {

FILE: packages/e2e/shared/specs/loader.tsx
  type SearchParams (line 13) | type SearchParams = inferParserType<typeof searchParams>
  type LoaderRendererProps (line 16) | type LoaderRendererProps = {
  function LoaderRenderer (line 20) | function LoaderRenderer({ serverValues }: LoaderRendererProps) {

FILE: packages/e2e/shared/specs/native-array.tsx
  function NativeArray (line 10) | function NativeArray() {

FILE: packages/e2e/shared/specs/popstate-queue-reset.spec.ts
  type TestPopstateQueueResetConfig (line 7) | type TestPopstateQueueResetConfig = TestConfig & {
  function testPopstateQueueReset (line 11) | function testPopstateQueueReset(config: TestPopstateQueueResetConfig) {

FILE: packages/e2e/shared/specs/popstate-queue-reset.tsx
  function PopstateQueueResetClient (line 7) | function PopstateQueueResetClient({
  function PopstateQueueResetOther (line 96) | function PopstateQueueResetOther() {

FILE: packages/e2e/shared/specs/pretty-urls.tsx
  function PrettyUrls (line 5) | function PrettyUrls() {

FILE: packages/e2e/shared/specs/push.tsx
  function PushUseQueryState (line 5) | function PushUseQueryState() {
  function PushUseQueryStates (line 15) | function PushUseQueryStates() {

FILE: packages/e2e/shared/specs/rate-limits.tsx
  constant UPDATE_RATE_MS (line 6) | const UPDATE_RATE_MS = 20
  constant RUN_TIME_MS (line 7) | const RUN_TIME_MS = 60_000
  type UpdateSuccess (line 9) | type UpdateSuccess = {
  type UpdateFailure (line 14) | type UpdateFailure = {
  type UpdateOutcome (line 20) | type UpdateOutcome = UpdateSuccess | UpdateFailure
  type TestHookResult (line 22) | type TestHookResult = {
  type ReducerState (line 32) | type ReducerState = {
  type ReducerAction (line 39) | type ReducerAction =
  function reducer (line 45) | function reducer(state: ReducerState, action: ReducerAction): ReducerSta...
  function useRateLimitTest (line 96) | function useRateLimitTest(): TestHookResult {
  function RateLimits (line 168) | function RateLimits() {

FILE: packages/e2e/shared/specs/react-router/fog-of-war.tsx
  function FogOfWarStartPage (line 4) | function FogOfWarStartPage({ resultHref }: { resultHref: string }) {
  function FogOfWarResultPage (line 20) | function FogOfWarResultPage() {

FILE: packages/e2e/shared/specs/react-router/repro-839-location-state-persistence.tsx
  type Repro839Props (line 3) | type Repro839Props = {
  function Repro839 (line 8) | function Repro839({ useNavigate, useLocation }: Repro839Props) {

FILE: packages/e2e/shared/specs/referential-stability.tsx
  function ReferentialStabilityUseQueryState (line 6) | function ReferentialStabilityUseQueryState() {
  function ReferentialStabilityUseQueryStates (line 18) | function ReferentialStabilityUseQueryStates() {

FILE: packages/e2e/shared/specs/render-count.params.ts
  type Params (line 25) | type Params = inferParserType<typeof params>
  type SearchParams (line 26) | type SearchParams = inferParserType<typeof searchParams>

FILE: packages/e2e/shared/specs/render-count.spec.ts
  type TestRenderCountConfig (line 6) | type TestRenderCountConfig = TestConfig & {
  function testRenderCount (line 19) | function testRenderCount({
  function times (line 58) | function times(n: number) {

FILE: packages/e2e/shared/specs/render-count.tsx
  type RenderCountProps (line 6) | type RenderCountProps = {
  function RenderCount (line 13) | function RenderCount({

FILE: packages/e2e/shared/specs/repro-1099.spec.ts
  type TestRepro1099Options (line 6) | type TestRepro1099Options = TestConfig & {
  function testRepro1099 (line 11) | function testRepro1099({

FILE: packages/e2e/shared/specs/repro-1099.tsx
  function Repro1099UseQueryState (line 8) | function Repro1099UseQueryState() {
  function Repro1099UseQueryStates (line 28) | function Repro1099UseQueryStates() {
  function useStateUpdateInEffect (line 59) | function useStateUpdateInEffect(trigger: unknown) {

FILE: packages/e2e/shared/specs/repro-1293.tsx
  type Props (line 6) | type Props = {
  function Repro1293PageA (line 15) | function Repro1293PageA({ linkHref }: Props) {
  function Repro1293PageB (line 31) | function Repro1293PageB() {

FILE: packages/e2e/shared/specs/repro-1365.tsx
  function Repro1365 (line 6) | function Repro1365() {

FILE: packages/e2e/shared/specs/repro-359.tsx
  function Repro359 (line 28) | function Repro359() {

FILE: packages/e2e/shared/specs/repro-982.tsx
  function Repro982 (line 6) | function Repro982() {

FILE: packages/e2e/shared/specs/routing.spec.ts
  type TestRoutingOptions (line 6) | type TestRoutingOptions = TestConfig & {
  function testRouting (line 11) | function testRouting({

FILE: packages/e2e/shared/specs/routing.tsx
  type Props (line 16) | type Props = {
  function RoutingUseQueryState (line 20) | function RoutingUseQueryState({ path }: Props) {
  function RoutingUseQueryStates (line 41) | function RoutingUseQueryStates({ path }: Props) {

FILE: packages/e2e/shared/specs/scroll.tsx
  function Scroll (line 6) | function Scroll() {
  function ScrollDetector (line 16) | function ScrollDetector() {
  function ScrollAction (line 37) | function ScrollAction() {

FILE: packages/e2e/shared/specs/shallow.spec.ts
  type TestShallowOptions (line 6) | type TestShallowOptions = TestConfig & {
  function testShallow (line 12) | function testShallow({

FILE: packages/e2e/shared/specs/shallow.tsx
  function ShallowUseQueryState (line 7) | function ShallowUseQueryState() {
  function ShallowUseQueryStates (line 18) | function ShallowUseQueryStates() {

FILE: packages/e2e/shared/specs/stitching.spec.ts
  type Config (line 7) | type Config = TestConfig & {
  function testStitching (line 11) | function testStitching({

FILE: packages/e2e/shared/specs/stitching.tsx
  function Stitching (line 7) | function Stitching() {
  function StitchingUseQueryState (line 18) | function StitchingUseQueryState() {
  function StitchingUseQueryStates (line 61) | function StitchingUseQueryStates() {

FILE: packages/e2e/tanstack-router/src/layout.tsx
  function Link (line 7) | function Link({ href, ...props }: LinkProps) {
  function useRouter (line 11) | function useRouter(): Router {
  function RootLayout (line 29) | function RootLayout({ children }: { children: ReactNode }) {

FILE: packages/e2e/tanstack-router/src/main.tsx
  type Register (line 20) | interface Register {

FILE: packages/e2e/tanstack-router/src/routes/linking.useQueryState.other.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/linking.useQueryState.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/linking.useQueryStates.other.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/linking.useQueryStates.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/routing.useQueryState.other.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/routing.useQueryState.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/routing.useQueryStates.other.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/routing.useQueryStates.tsx
  function Page (line 8) | function Page() {

FILE: packages/e2e/tanstack-router/src/routes/trailing-slash.tsx
  function TrailingSlashTest (line 23) | function TrailingSlashTest() {

FILE: packages/examples/next-app/src/app/_components/filter.tsx
  function Filter (line 6) | function Filter() {

FILE: packages/examples/next-app/src/app/_components/pagination.tsx
  function Pagination (line 7) | function Pagination({ total }: { total: number }) {

FILE: packages/examples/next-app/src/app/_components/users-list.tsx
  function UsersList (line 5) | async function UsersList() {

FILE: packages/examples/next-app/src/app/layout.tsx
  function RootLayout (line 21) | function RootLayout({

FILE: packages/examples/next-app/src/app/page.tsx
  type PageProps (line 8) | type PageProps = {
  function Home (line 12) | async function Home({ searchParams }: PageProps) {

FILE: packages/examples/next-app/src/data.ts
  type GetUsersOptions (line 84) | interface GetUsersOptions {
  function getUsers (line 91) | async function getUsers({

FILE: packages/examples/trpc/app/components/inverted-coordinates.tsx
  function InvertedCoordinates (line 5) | function InvertedCoordinates() {

FILE: packages/examples/trpc/app/components/random-coordinates.tsx
  function RandomCoordinates (line 3) | function RandomCoordinates() {

FILE: packages/examples/trpc/app/root.tsx
  function makeQueryClient (line 18) | function makeQueryClient() {
  function getQueryClient (line 32) | function getQueryClient() {
  function Layout (line 46) | function Layout({ children }: { children: React.ReactNode }) {
  function App (line 64) | function App() {
  function ErrorBoundary (line 87) | function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {

FILE: packages/examples/trpc/app/routes/api/trpc.ts
  function handleRequest (line 13) | function handleRequest(args: LoaderFunctionArgs | ActionFunctionArgs) {

FILE: packages/examples/trpc/app/routes/index.tsx
  function Page (line 4) | function Page() {

FILE: packages/examples/trpc/app/search-params.ts
  function useCoordinates (line 25) | function useCoordinates() {

FILE: packages/examples/trpc/app/server/trpc.ts
  type AppRouter (line 33) | type AppRouter = typeof appRouter

FILE: packages/examples/trpc/server.mjs
  function run (line 15) | async function run() {

FILE: packages/nuqs/src/adapters/lib/context.ts
  type AdapterProps (line 15) | type AdapterProps = {
  type AdapterContext (line 22) | type AdapterContext = AdapterProps & {
  method useAdapter (line 27) | useAdapter() {
  type Window (line 34) | interface Window {
  type AdapterProvider (line 46) | type AdapterProvider = (
  function createAdapterProvider (line 60) | function createAdapterProvider(
  function useAdapter (line 74) | function useAdapter(watchKeys: string[]): AdapterInterface {

FILE: packages/nuqs/src/adapters/lib/defs.ts
  type AdapterOptions (line 3) | type AdapterOptions = Pick<Options, 'history' | 'scroll' | 'shallow'>
  type UpdateUrlFunction (line 5) | type UpdateUrlFunction = (
  type UseAdapterHook (line 10) | type UseAdapterHook = (watchKeys: string[]) => AdapterInterface
  type AdapterInterface (line 12) | type AdapterInterface = {

FILE: packages/nuqs/src/adapters/lib/key-isolation.ts
  function applyChange (line 4) | function applyChange(
  function filterSearchParams (line 37) | function filterSearchParams(

FILE: packages/nuqs/src/adapters/lib/patch-history.ts
  type SearchParamsSyncEmitterEvents (line 6) | type SearchParamsSyncEmitterEvents = { update: URLSearchParams }
  type History (line 11) | interface History {
  function getSearchParams (line 19) | function getSearchParams(url: string | URL): URLSearchParams {
  function shouldPatchHistory (line 33) | function shouldPatchHistory(adapter: string): boolean {
  function markHistoryAsPatched (line 55) | function markHistoryAsPatched(adapter: string): void {
  function patchHistory (line 64) | function patchHistory(

FILE: packages/nuqs/src/adapters/lib/react-router.ts
  type NavigateUrl (line 16) | type NavigateUrl = {
  type NavigateOptions (line 20) | type NavigateOptions = {
  type NavigateFn (line 25) | type NavigateFn = (url: NavigateUrl, options: NavigateOptions) => void
  type UseNavigate (line 26) | type UseNavigate = () => NavigateFn
  type UseSearchParams (line 27) | type UseSearchParams = (initial: URLSearchParams) => [URLSearchParams, {}]
  type CreateReactRouterBasedAdapterArgs (line 31) | type CreateReactRouterBasedAdapterArgs = {
  function createReactRouterBasedAdapter (line 37) | function createReactRouterBasedAdapter({

FILE: packages/nuqs/src/adapters/next.ts
  function useNuqsNextAdapter (line 6) | function useNuqsNextAdapter(): AdapterInterface {

FILE: packages/nuqs/src/adapters/next/app.ts
  function NuqsAdapter (line 12) | function NuqsAdapter({

FILE: packages/nuqs/src/adapters/next/impl.app.ts
  constant NUM_HISTORY_CALLS_PER_UPDATE (line 26) | const NUM_HISTORY_CALLS_PER_UPDATE = 3
  function onPopState (line 28) | function onPopState() {
  function onHistoryStateUpdate (line 33) | function onHistoryStateUpdate() {
  function patchHistory (line 45) | function patchHistory() {
  function NavigationSpy (line 89) | function NavigationSpy() {
  function useNuqsNextAppRouterAdapter (line 110) | function useNuqsNextAppRouterAdapter(): AdapterInterface {
  function renderURL (line 158) | function renderURL(search: URLSearchParams) {

FILE: packages/nuqs/src/adapters/next/impl.pages.ts
  type Window (line 10) | interface Window {
  function isPagesRouter (line 21) | function isPagesRouter(): boolean {
  function onNavigation (line 27) | function onNavigation() {
  function useNuqsNextPagesRouterAdapter (line 34) | function useNuqsNextPagesRouterAdapter(): AdapterInterface {
  function getAsPathPathname (line 118) | function getAsPathPathname(asPath: string): string {
  function urlSearchParamsToObject (line 124) | function urlSearchParamsToObject(
  function extractDynamicUrlParams (line 148) | function extractDynamicUrlParams(

FILE: packages/nuqs/src/adapters/react.ts
  function generateUpdateUrlFn (line 25) | function generateUpdateUrlFn(fullPageNavigationOnShallowFalseUpdates: bo...
  function useNuqsReactAdapter (line 50) | function useNuqsReactAdapter(watchKeys: string[]): AdapterInterface {
  function NuqsAdapter (line 94) | function NuqsAdapter({
  function enableHistorySync (line 116) | function enableHistorySync(): void {

FILE: packages/nuqs/src/adapters/tanstack-router.ts
  function useNuqsTanstackRouterAdapter (line 7) | function useNuqsTanstackRouterAdapter(watchKeys: string[]): AdapterInter...

FILE: packages/nuqs/src/adapters/testing.ts
  type UrlUpdateEvent (line 15) | type UrlUpdateEvent = {
  type OnUrlUpdateFunction (line 21) | type OnUrlUpdateFunction = (event: UrlUpdateEvent) => void
  type TestingAdapterProps (line 23) | type TestingAdapterProps = Pick<AdapterInterface, 'autoResetQueueOnUpdat...
  function renderInitialSearchParams (line 65) | function renderInitialSearchParams(
  function NuqsTestingAdapter (line 80) | function NuqsTestingAdapter({
  function withNuqsTestingAdapter (line 156) | function withNuqsTestingAdapter(

FILE: packages/nuqs/src/cache.test.ts
  method cache (line 8) | cache<T, CachedFunction extends () => T>(fn: CachedFunction) {

FILE: packages/nuqs/src/cache.ts
  type CacheInterface (line 9) | type CacheInterface<Parsers extends ParserMap> = {
  function createSearchParamsCache (line 53) | function createSearchParamsCache<Parsers extends ParserMap>(
  function compareSearchParams (line 139) | function compareSearchParams(a: SearchParams, b: SearchParams): boolean {

FILE: packages/nuqs/src/defs.ts
  type SearchParams (line 3) | type SearchParams = Record<string, string | string[] | undefined>
  type HistoryOptions (line 4) | type HistoryOptions = 'replace' | 'push'
  type LimitUrlUpdates (line 5) | type LimitUrlUpdates =
  type Options (line 9) | type Options = {
  type Nullable (line 92) | type Nullable<T> = {
  type UrlKeys (line 124) | type UrlKeys<Parsers extends Record<string, any>> = Partial<

FILE: packages/nuqs/src/lib/compare.ts
  function compareQuery (line 3) | function compareQuery<T extends Query>(

FILE: packages/nuqs/src/lib/compose.ts
  function compose (line 1) | function compose(

FILE: packages/nuqs/src/lib/debug.ts
  function debug (line 3) | function debug(message: string, ...args: any[]): void {
  function warn (line 17) | function warn(message: string, ...args: any[]): void {
  function sprintf (line 24) | function sprintf(base: string, ...args: any[]): string {
  function isDebugEnabled (line 33) | function isDebugEnabled(): boolean {

FILE: packages/nuqs/src/lib/emitter.test.ts
  type Events (line 4) | type Events = {

FILE: packages/nuqs/src/lib/emitter.ts
  type Emitter (line 1) | type Emitter<Events extends Record<string, unknown>> = {
  function createEmitter (line 16) | function createEmitter<

FILE: packages/nuqs/src/lib/errors.ts
  function error (line 12) | function error(code: keyof typeof errors) {

FILE: packages/nuqs/src/lib/queues/debounce.test.ts
  function passThrough (line 7) | async function passThrough<T>(value: T): Promise<T> {
  method getSearchParamsSnapshot (line 111) | getSearchParamsSnapshot() {
  method getSearchParamsSnapshot (line 142) | getSearchParamsSnapshot() {
  method getSearchParamsSnapshot (line 175) | getSearchParamsSnapshot() {
  method getSearchParamsSnapshot (line 210) | getSearchParamsSnapshot() {
  method getSearchParamsSnapshot (line 239) | getSearchParamsSnapshot() {
  method getSearchParamsSnapshot (line 259) | getSearchParamsSnapshot() {

FILE: packages/nuqs/src/lib/queues/debounce.ts
  class DebouncedPromiseQueue (line 15) | class DebouncedPromiseQueue<ValueType, OutputType> {
    method constructor (line 21) | constructor(callback: (value: ValueType) => Promise<OutputType>) {
    method abort (line 25) | abort(): void {
    method push (line 30) | push(value: ValueType, timeMs: number): Promise<OutputType> {
  type DebouncedUpdateQueue (line 63) | type DebouncedUpdateQueue = DebouncedPromiseQueue<
  class DebounceController (line 68) | class DebounceController {
    method constructor (line 73) | constructor(throttleQueue: ThrottledQueue = new ThrottledQueue()) {
    method useQueuedQueries (line 77) | useQueuedQueries(keys: string[]): Record<string, Query | null | undefi...
    method push (line 85) | push(
    method abort (line 123) | abort(
    method abortAll (line 145) | abortAll(): void {
    method getQueuedQuery (line 160) | getQueuedQuery(key: string): Query | null | undefined {

FILE: packages/nuqs/src/lib/queues/rate-limiting.ts
  function getDefaultThrottle (line 6) | function getDefaultThrottle() {
  function throttle (line 22) | function throttle(timeMs: number): LimitUrlUpdates {
  function debounce (line 26) | function debounce(timeMs: number): LimitUrlUpdates {

FILE: packages/nuqs/src/lib/queues/reset.ts
  function setQueueResetMutex (line 7) | function setQueueResetMutex(value = 1): void {
  function spinQueueResetMutex (line 11) | function spinQueueResetMutex(onReset: () => void = resetQueues): void {
  function resetQueues (line 20) | function resetQueues(): void {

FILE: packages/nuqs/src/lib/queues/throttle.test.ts
  function createMockAdapter (line 6) | function createMockAdapter(): UpdateQueueAdapterContext {
  method getSearchParamsSnapshot (line 293) | getSearchParamsSnapshot() {

FILE: packages/nuqs/src/lib/queues/throttle.ts
  type UpdateMap (line 11) | type UpdateMap = Map<string, Query | null>
  type TransitionSet (line 12) | type TransitionSet = Set<React.TransitionStartFunction>
  type UpdateQueueAdapterContext (line 13) | type UpdateQueueAdapterContext = Pick<
  type UpdateQueuePushArgs (line 21) | type UpdateQueuePushArgs = {
  function getSearchParamsSnapshotFromLocation (line 27) | function getSearchParamsSnapshotFromLocation(): URLSearchParams {
  class ThrottledQueue (line 31) | class ThrottledQueue {
    method push (line 45) | push(
    method getQueuedQuery (line 74) | getQueuedQuery(key: string): Query | null | undefined {
    method getPendingPromise (line 78) | getPendingPromise({
    method flush (line 84) | flush(
    method abort (line 147) | abort(): string[] {
    method reset (line 156) | reset(): string[] {
    method applyPendingUpdates (line 173) | applyPendingUpdates(

FILE: packages/nuqs/src/lib/queues/useSyncExternalStores.ts
  function useSyncExternalStores (line 17) | function useSyncExternalStores<T>(

FILE: packages/nuqs/src/lib/safe-parse.ts
  function safeParse (line 3) | function safeParse<I, R>(

FILE: packages/nuqs/src/lib/search-params.ts
  type Query (line 1) | type Query = string | Array<string>
  function isAbsentFromUrl (line 3) | function isAbsentFromUrl(query: Query | null): query is null | [] {
  function write (line 7) | function write(

FILE: packages/nuqs/src/lib/sync.browser.test.tsx
  type TestComponentProps (line 8) | type TestComponentProps = {

FILE: packages/nuqs/src/lib/sync.ts
  type CrossHookSyncPayload (line 4) | type CrossHookSyncPayload = {
  type EventMap (line 9) | type EventMap = {

FILE: packages/nuqs/src/lib/timeout.ts
  function timeout (line 4) | function timeout(

FILE: packages/nuqs/src/lib/url-encoding.ts
  function renderQueryString (line 3) | function renderQueryString(search: URLSearchParams): string {
  function encodeQueryValue (line 24) | function encodeQueryValue(input: string): string {
  constant URL_MAX_LENGTH (line 51) | const URL_MAX_LENGTH = 2000
  function warnIfURLIsTooLong (line 53) | function warnIfURLIsTooLong(queryString: string): void {

FILE: packages/nuqs/src/lib/with-resolvers.ts
  type Resolvers (line 1) | type Resolvers<T> = {
  function withResolvers (line 7) | function withResolvers<T>(): Resolvers<T> {

FILE: packages/nuqs/src/loader.ts
  type LoaderInput (line 5) | type LoaderInput =
  type LoaderOptions (line 15) | type LoaderOptions<Parsers extends ParserMap> = {
  type CreateLoaderOptions (line 18) | type CreateLoaderOptions<P extends ParserMap> = LoaderOptions<P>
  type LoaderFunctionOptions (line 19) | type LoaderFunctionOptions = {
  type LoaderFunction (line 28) | type LoaderFunction<Parsers extends ParserMap> = {
  function createLoader (line 73) | function createLoader<Parsers extends ParserMap>(
  function extractSearchParams (line 132) | function extractSearchParams(input: LoaderInput): URLSearchParams {

FILE: packages/nuqs/src/parsers.test.ts
  type Test (line 143) | enum Test {

FILE: packages/nuqs/src/parsers.ts
  type Require (line 5) | type Require<T, Keys extends keyof T> = Pick<Required<T>, Keys> & Omit<T...
  type SingleParser (line 7) | type SingleParser<T> = {
  type MultiParser (line 34) | type MultiParser<T> = {
  type GenericParser (line 41) | type GenericParser<T> = SingleParser<T> | MultiParser<T>
  type GenericParserBuilder (line 42) | type GenericParserBuilder<T> =
  type Parser (line 48) | type Parser<T> = SingleParser<T>
  type ParserBuilder (line 50) | type ParserBuilder<T> = SingleParserBuilder<T>
  type SingleParserBuilder (line 52) | type SingleParserBuilder<T> = Required<SingleParser<T>> &
  type MultiParserBuilder (line 125) | type MultiParserBuilder<T> = Required<MultiParser<T>> &
  function createParser (line 150) | function createParser<T>(
  function createMultiParser (line 195) | function createMultiParser<T>(
  function compareDates (line 275) | function compareDates(a: Date, b: Date) {
  function parseAsStringEnum (line 351) | function parseAsStringEnum<Enum extends string>(
  function parseAsStringLiteral (line 377) | function parseAsStringLiteral<const Literal extends string>(
  function parseAsNumberLiteral (line 408) | function parseAsNumberLiteral<const Literal extends number>(
  function parseAsJson (line 430) | function parseAsJson<T>(
  function parseAsArrayOf (line 466) | function parseAsArrayOf<ItemType>(
  function parseAsNativeArrayOf (line 512) | function parseAsNativeArrayOf<ItemType>(
  type inferSingleParserType (line 543) | type inferSingleParserType<Parser> = Parser extends GenericParserBuilder<
  type inferParserRecordType (line 553) | type inferParserRecordType<
  type inferParserType (line 583) | type inferParserType<Input> =
  type ParserWithOptionalDefault (line 590) | type ParserWithOptionalDefault<T> = GenericParserBuilder<T> & {
  type ParserMap (line 593) | type ParserMap = Record<string, ParserWithOptionalDefault<any>>

FILE: packages/nuqs/src/serializer.ts
  type Base (line 6) | type Base = string | URLSearchParams | URL
  type CreateSerializerOptions (line 8) | type CreateSerializerOptions<Parsers extends ParserMap> = Pick<
  type SerializeFunction (line 16) | type SerializeFunction<
  function createSerializer (line 39) | function createSerializer<
  function isBase (line 114) | function isBase<BaseType>(base: any): base is BaseType {
  function splitBase (line 122) | function splitBase<BaseType extends Base>(base: BaseType) {

FILE: packages/nuqs/src/standard-schema.ts
  type CreateStandardSchemaV1Options (line 6) | type CreateStandardSchemaV1Options<
  type MaybePartial (line 23) | type MaybePartial<Condition, Type> = Condition extends true
  function createStandardSchemaV1 (line 27) | function createStandardSchemaV1<

FILE: packages/nuqs/src/testing.ts
  function isParserBijective (line 39) | function isParserBijective<T>(
  function testSerializeThenParse (line 107) | function testSerializeThenParse<T>(
  function testParseThenSerialize (line 161) | function testParseThenSerialize<T>(

FILE: packages/nuqs/src/useQueryState.browser.test.tsx
  function TestComponent (line 457) | function TestComponent() {

FILE: packages/nuqs/src/useQueryState.ts
  type UseQueryStateOptions (line 6) | type UseQueryStateOptions<T> = GenericParser<T> & Options
  type UseQueryStateReturn (line 8) | type UseQueryStateReturn<Parsed, Default> = [
  function useQueryState (line 194) | function useQueryState<T = string>(

FILE: packages/nuqs/src/useQueryStates.browser.test.tsx
  function TestComponent (line 263) | function TestComponent() {
  function DynamicWrapper (line 948) | function DynamicWrapper({ children }: { children: ReactNode }) {
  function TestComponent (line 1012) | function TestComponent() {

FILE: packages/nuqs/src/useQueryStates.ts
  type KeyMapValue (line 22) | type KeyMapValue<Type> = GenericParser<Type> &
  type UseQueryStatesKeysMap (line 27) | type UseQueryStatesKeysMap<Map = any> = {
  type UseQueryStatesOptions (line 31) | type UseQueryStatesOptions<KeyMap extends UseQueryStatesKeysMap> =
  type Values (line 36) | type Values<T extends UseQueryStatesKeysMap> = {
  type NullableValues (line 43) | type NullableValues<T extends UseQueryStatesKeysMap> = Nullable<Values<T>>
  type UpdaterFn (line 45) | type UpdaterFn<T extends UseQueryStatesKeysMap> = (
  type SetValues (line 49) | type SetValues<T extends UseQueryStatesKeysMap> = (
  type UseQueryStatesReturn (line 54) | type UseQueryStatesReturn<T extends UseQueryStatesKeysMap> = [
  function useQueryStates (line 72) | function useQueryStates<KeyMap extends UseQueryStatesKeysMap>(
  function parseMap (line 397) | function parseMap<KeyMap extends UseQueryStatesKeysMap>(
  function applyDefaultValues (line 454) | function applyDefaultValues<KeyMap extends UseQueryStatesKeysMap>(

FILE: packages/nuqs/tests/cache.test-d.ts
  type All (line 15) | type All = Readonly<{ foo: string | null; bar: number | null; egg: boole...

FILE: packages/nuqs/tests/components/repro-1099.tsx
  type NullDetectorProps (line 9) | type NullDetectorProps = ComponentProps<'pre'> & {
  function NullDetector (line 14) | function NullDetector({
  function useFakeLoadingState (line 31) | function useFakeLoadingState(trigger: unknown): boolean {

FILE: packages/nuqs/tests/parsers.test-d.ts
  type Test (line 69) | enum Test {
  type T (line 91) | type T = { test: string }

FILE: packages/nuqs/tests/useQueryState.test-d.ts
  method parse (line 51) | parse(query) {
  method serialize (line 61) | serialize(value) {
  method eq (line 71) | eq(a, b) {

FILE: packages/nuqs/tsdown.config.ts
  method outExtensions (line 18) | outExtensions() {
  method onSuccess (line 58) | async onSuccess() {

FILE: packages/scripts/next-release-analyser.ts
  type File (line 29) | type File = z.infer<typeof fileSchema>
  function main (line 31) | async function main() {
  function getPreviousVersion (line 64) | function getPreviousVersion(version: string) {
  function sendNotificationEmail (line 76) | async function sendNotificationEmail(thisVersion: string, files: File[]) {
  function sendGAEmail (line 116) | function sendGAEmail(thisVersion: string) {

FILE: packages/scripts/release-notes-automation.test.ts
  function createPR (line 13) | function createPR(

FILE: packages/scripts/release-notes-automation.ts
  type PR (line 47) | type PR = z.infer<typeof prSchema>
  constant CATEGORIES (line 49) | const CATEGORIES = [
  type Category (line 55) | type Category = (typeof CATEGORIES)[number]
  function fetchMilestonePRs (line 57) | async function fetchMilestonePRs(): Promise<PR[]> {
  function splitCategoryTitle (line 127) | function splitCategoryTitle(title: string): [Category, string] {
  type CategorizedPR (line 159) | type CategorizedPR = {
  function groupPRsByCategory (line 167) | function groupPRsByCategory(
  function isBot (line 208) | function isBot(login: string) {
  function collectContributors (line 212) | function collectContributors(prs: PR[]): string[] {
  function formatClosingIssues (line 241) | function formatClosingIssues(
  function formatTitle (line 249) | function formatTitle(title: string): string {
  function formatThanksSection (line 254) | function formatThanksSection(contributors: string[]): string | null {
  function main (line 266) | async function main() {
Condensed preview — 1140 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,895K chars).
[
  {
    "path": ".agents/docs/adapter-development.md",
    "chars": 3342,
    "preview": "# Adapter Development\n\nGuide for adding framework adapters to nuqs.\n\n## Overview\n\nAdapters wrap the app root and provide"
  },
  {
    "path": ".agents/docs/api-design.md",
    "chars": 3445,
    "preview": "# API Design & Architecture\n\nGuide for maintaining API stability, designing extensions, and understanding the architectu"
  },
  {
    "path": ".agents/docs/git-workflow.md",
    "chars": 4376,
    "preview": "# Release & Git Workflow\n\nGuide for versioning, commits, pull requests, and release process.\n\n## Conventional Commits\n\nA"
  },
  {
    "path": ".agents/docs/parser-implementation.md",
    "chars": 3870,
    "preview": "# Parser Implementation\n\nGuide for creating custom parsers and understanding parser semantics.\n\n## Overview\n\nParsers are"
  },
  {
    "path": ".agents/docs/quality-standards.md",
    "chars": 5341,
    "preview": "# Quality Standards\n\nGuide for performance, security, reliability, and quality assurance.\n\n## Exit Conditions for Agent "
  },
  {
    "path": ".agents/docs/testing.md",
    "chars": 3942,
    "preview": "# Testing Patterns\n\nGuide for testing strategy, test organization, and regression workflows.\n\n## Full Test Suite\n\nRun th"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 101,
    "preview": "github: [franky47]\nliberapay: francoisbest\ncustom: ['https://paypal.me/francoisbest?locale.x=fr_FR']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1191,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n---\n\n<!--\nPlease read"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 349,
    "preview": "blank_issues_enabled: true\ncontact_links:\n  - name: Feature idea\n    url: https://github.com/47ng/nuqs/discussions/new?c"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 323,
    "preview": "version: 2\nupdates:\n  # - package-ecosystem: npm\n  #   directory: /\n  #   schedule:\n  #     interval: weekly\n  #     tim"
  },
  {
    "path": ".github/workflows/analyse-nextjs-release.yml",
    "chars": 1864,
    "preview": "name: \"Analyse Next.js release\"\nrun-name: \"Analyse Next.js ${{ inputs.version }}\"\n\non:\n  workflow_dispatch:\n    inputs:\n"
  },
  {
    "path": ".github/workflows/ci-cd.yml",
    "chars": 18825,
    "preview": "name: CI/CD\n\non:\n  push:\n    branches:\n      - master\n      - beta\n      - next\n  pull_request:\n    types: [opened, reop"
  },
  {
    "path": ".github/workflows/clear-shipping-next.yml",
    "chars": 1814,
    "preview": "name: Clear \"Shipping Next\"\n\non:\n  workflow_dispatch:\n\nenv:\n  SHIPPING_NEXT_MILESTONE_ID: 2 # ID for \"Shipping Next\" mil"
  },
  {
    "path": ".github/workflows/milestone-automation.yml",
    "chars": 4693,
    "preview": "name: Mark as \"Shipping Next\"\n\non:\n  pull_request_target:\n    types: [closed]\n    branches:\n      - next\n\nenv:\n  BACKLOG"
  },
  {
    "path": ".github/workflows/pkg.pr.new.yml",
    "chars": 1558,
    "preview": "name: PR Preview\non:\n  pull_request:\n    types: [opened, synchronize, labeled]\n    paths:\n      - 'packages/nuqs/**'\n\nco"
  },
  {
    "path": ".github/workflows/pr-base-enforcement.yml",
    "chars": 768,
    "preview": "name: Prevent PRs targetting master\n\non:\n  pull_request:\n    types: [opened, edited]\n    branches:\n      - master\n\njobs:"
  },
  {
    "path": ".github/workflows/pr-lint.yml",
    "chars": 5036,
    "preview": "name: Lint PR Title\n\non:\n  pull_request:\n    types:\n      - opened\n      - edited\n      - synchronize\n\njobs:\n  lint-pr-t"
  },
  {
    "path": ".github/workflows/test-against-nextjs-release.yml",
    "chars": 5842,
    "preview": "name: \"Test against Next.js release\"\nrun-name: \"Test against Next.js ${{ inputs.version }}\"\n\non:\n  workflow_dispatch:\n  "
  },
  {
    "path": ".gitignore",
    "chars": 152,
    "preview": "node_modules/\ndist/\ncoverage/\n.env\nyarn-error.log\n# Docker containers with persistance\n.volumes/\npackage-lock.json\n.next"
  },
  {
    "path": ".husky/commit-msg",
    "chars": 26,
    "preview": "pnpm commitlint --edit $1\n"
  },
  {
    "path": ".node-version",
    "chars": 8,
    "preview": "24.11.0\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 1104,
    "preview": "{\n  \"editor.tabSize\": 2,\n  \"editor.insertSpaces\": true,\n  \"githubPullRequests.ignoredPullRequestBranches\": [\"next\", \"mas"
  },
  {
    "path": "AGENTS.md",
    "chars": 3867,
    "preview": "# AGENTS GUIDE\n\nOperational instructions for autonomous coding / AI agents contributing to the nuqs repository.\n\n**nuqs*"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5226,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3118,
    "preview": "# Contribution Guidelines\n\nFirst off, thanks for your help! 🙏\n\n## Getting started\n\n1. Fork and clone the repository\n2. I"
  },
  {
    "path": "LICENSE",
    "chars": 1097,
    "preview": "MIT License\n\nCopyright (c) 2020 François Best <contact@francoisbest.com>\n\nPermission is hereby granted, free of charge, "
  },
  {
    "path": "README.md",
    "chars": 29038,
    "preview": "# nuqs\n\n[![NPM](https://img.shields.io/npm/v/nuqs?color=red)](https://www.npmjs.com/package/nuqs)\n[![MIT License](https:"
  },
  {
    "path": "errors/NUQS-101.md",
    "chars": 896,
    "preview": "# This package is ESM only.\n\nSince version 2.0.0, `nuqs` is now an [ESM-only package](https://gist.github.com/sindresorh"
  },
  {
    "path": "errors/NUQS-303.md",
    "chars": 759,
    "preview": "# Multiple adapter contexts detected\n\n## Probable cause\n\nThis error occurs in [debug mode](https://nuqs.dev/docs/debuggi"
  },
  {
    "path": "errors/NUQS-404.md",
    "chars": 1860,
    "preview": "# `nuqs` requires an adapter to work with your framework\n\n## Probable cause\n\nYou haven't wrapped the components calling "
  },
  {
    "path": "errors/NUQS-409.md",
    "chars": 424,
    "preview": "# Multiple versions of the library are loaded\n\nThis error occurs if two different versions of `nuqs` are\nloaded in the s"
  },
  {
    "path": "errors/NUQS-414.md",
    "chars": 1121,
    "preview": "# Max Safe URL Length Exceeded\n\nThis error occurs if your URL length exceeds 2,000 characters.\n\nThere are varying browse"
  },
  {
    "path": "errors/NUQS-422.md",
    "chars": 659,
    "preview": "# Invalid Options Combination.\n\nThis warning will show up if you combine `shallow: true` (the default) and `limitUrlUpda"
  },
  {
    "path": "errors/NUQS-429.md",
    "chars": 582,
    "preview": "# URL update rate-limited by the browser\n\nThis error occurs when too many URL updates are attempted in a short period of"
  },
  {
    "path": "errors/NUQS-500.md",
    "chars": 1588,
    "preview": "# Empty Search Params Cache\n\nThis error shows up on the server when trying to access a searchParam from\na cache created "
  },
  {
    "path": "errors/NUQS-501.md",
    "chars": 527,
    "preview": "# Search params cache already populated\n\nThis error occurs when a [search params cache](https://github.com/47ng/nuqs#acc"
  },
  {
    "path": "package.json",
    "chars": 1795,
    "preview": "{\n  \"name\": \"nuqs-monorepo\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"license\": \"MIT\",\n  \"author\": {\n    \"name\": \"Fra"
  },
  {
    "path": "packages/docs/.gitignore",
    "chars": 345,
    "preview": "# deps\n/node_modules\n\n# generated content\n_map.ts\n.contentlayer\n.source\n\n# test & build\n/coverage\n/.next/\n/out/\n/build\n*"
  },
  {
    "path": "packages/docs/README.md",
    "chars": 584,
    "preview": "# docs\n\nThis is a Next.js application generated with\n[Fumadocs](https://github.com/fuma-nama/fumadocs).\n\nRun development"
  },
  {
    "path": "packages/docs/components.json",
    "chars": 353,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"default\",\n  \"rsc\": true,\n  \"tsx\": true,\n  \"tailwind\": {\n"
  },
  {
    "path": "packages/docs/content/blog/2025.mdx",
    "chars": 9436,
    "preview": "---\ntitle: '2025'\ndescription: A look back on an amazing year of OSS, meeting people, and milestones.\nauthor: François B"
  },
  {
    "path": "packages/docs/content/blog/beware-the-url-type-safety-iceberg.components.tsx",
    "chars": 2346,
    "preview": "'use client'\n\nimport { useState } from 'react'\n\nconst states = {\n  pagination: {\n    pageIndex: 1,\n    pageSize: 50\n  },"
  },
  {
    "path": "packages/docs/content/blog/beware-the-url-type-safety-iceberg.mdx",
    "chars": 10834,
    "preview": "---\ntitle: Beware The URL Type-Safety Iceberg\ndescription: Type-safe URL state is only the visible part. There are more "
  },
  {
    "path": "packages/docs/content/blog/nuqs-2.5-key-isolation.client.tsx",
    "chars": 2566,
    "preview": "'use client'\n\nimport { Button } from '@/src/components/ui/button'\nimport { parseAsInteger, useQueryState } from 'nuqs'\ni"
  },
  {
    "path": "packages/docs/content/blog/nuqs-2.5.mdx",
    "chars": 20516,
    "preview": "---\ntitle: nuqs 2.5\ndescription: Debounce, Standard Schema, TanStack Router, Key isolation, Global defaults, and more…\na"
  },
  {
    "path": "packages/docs/content/blog/nuqs-2.mdx",
    "chars": 6576,
    "preview": "---\ntitle: nuqs 2\ndescription: Opening up to other React frameworks\nauthor: François Best\ndate: 2024-10-22\n---\n\nnuqs@2.0"
  },
  {
    "path": "packages/docs/content/blog/open-source-pledge-recipient.tsx",
    "chars": 535,
    "preview": "type OpenSourcePledgeRecipientProps = {\n  handle: string\n  name: string\n}\n\nexport function OpenSourcePledgeRecipient({\n "
  },
  {
    "path": "packages/docs/content/blog/open-source-pledge.mdx",
    "chars": 4797,
    "preview": "---\ntitle: Signing the Open Source Pledge\ndescription: Giving back to maintainers of the OSS projects nuqs depends on.\na"
  },
  {
    "path": "packages/docs/content/docs/about.mdx",
    "chars": 1313,
    "preview": "---\ntitle: About\ndescription: About the nuqs library\n---\n\n## License\n\nReleased under the [MIT License](https://github.co"
  },
  {
    "path": "packages/docs/content/docs/adapters.mdx",
    "chars": 8461,
    "preview": "---\ntitle: Adapters\ndescription: Using nuqs in your React framework of choice\n---\n\nimport {\n  NextJS,\n  ReactRouter,\n  R"
  },
  {
    "path": "packages/docs/content/docs/basic-usage.mdx",
    "chars": 3788,
    "preview": "---\ntitle: Basic usage\ndescription: Replacing React.useState with useQueryState\n---\n\nimport {\n  DemoFallback,\n  BasicUsa"
  },
  {
    "path": "packages/docs/content/docs/batching.mdx",
    "chars": 4702,
    "preview": "---\ntitle: useQueryStates\ndescription: How to read & update multiple search params at once\n---\n\n## Multiple updates (bat"
  },
  {
    "path": "packages/docs/content/docs/debugging.mdx",
    "chars": 1441,
    "preview": "---\ntitle: Debugging\ndescription: Enabling debug logs and user timings markers\n---\n\n## Browser\n\nYou can enable debug log"
  },
  {
    "path": "packages/docs/content/docs/installation.mdx",
    "chars": 1509,
    "preview": "---\ntitle: Installation\ndescription: Getting started\n---\n\nimport {\n  NextJS,\n  ReactRouter,\n  ReactRouterV7,\n  ReactSPA,"
  },
  {
    "path": "packages/docs/content/docs/internal/design-system.mdx",
    "chars": 2430,
    "preview": "---\ntitle: Design System\ndescription: Who needs Storybook anyway?\nexposeTo: [user]\n---\n\nimport { H1, H2, Description } f"
  },
  {
    "path": "packages/docs/content/docs/limits.mdx",
    "chars": 1528,
    "preview": "---\ntitle: Limits\ndescription: There are some limits you should be aware of when using nuqs or URL params in general.\n--"
  },
  {
    "path": "packages/docs/content/docs/meta.json",
    "chars": 409,
    "preview": "{\n  \"title\": \"Documentation\",\n  \"root\": true,\n  \"pages\": [\n    \"---Getting started---\",\n    \"installation\",\n    \"adapter"
  },
  {
    "path": "packages/docs/content/docs/migrations/v2.mdx",
    "chars": 8484,
    "preview": "---\ntitle: Migration guide to v2\ndescription: How to update your code to use nuqs@2.0.0\n---\n\nHere's a summary of the bre"
  },
  {
    "path": "packages/docs/content/docs/options.client.tsx",
    "chars": 3086,
    "preview": "'use client'\n\nimport { QuerySpy } from '@/src/components/query-spy'\nimport { Button } from '@/src/components/ui/button'\n"
  },
  {
    "path": "packages/docs/content/docs/options.mdx",
    "chars": 14613,
    "preview": "---\ntitle: Options\ndescription: Configuring nuqs\n---\n\nBy default, `nuqs` will update search params:\n1. On the client onl"
  },
  {
    "path": "packages/docs/content/docs/parsers/built-in.mdx",
    "chars": 8838,
    "preview": "---\ntitle: Built-in parsers\ndescription: When using strings is not enough\n---\n\nimport {\n  DemoFallback,\n  IntegerParserD"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/effect-schema-demo.tsx",
    "chars": 4676,
    "preview": "'use client'\n\nimport { CodeBlock } from '@/src/components/code-block.client'\nimport { QuerySpy } from '@/src/components/"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/effect-schema.mdx",
    "chars": 1770,
    "preview": "---\ntitle: Effect Schema Parsers\ndescription: Use Effect Schema to parse and serialize URL state.\n---\n\n[Effect](https://"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/meta.json",
    "chars": 89,
    "preview": "{\n  \"title\": \"Community\",\n  \"pages\": [\"tanstack-table\", \"effect-schema\", \"zod-codecs\"]\n}\n"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/tanstack-table.generator.tsx",
    "chars": 7869,
    "preview": "'use client'\n\nimport { CodeBlock } from '@/src/components/code-block.client'\nimport { Querystring } from '@/src/componen"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/tanstack-table.mdx",
    "chars": 1065,
    "preview": "---\ntitle: TanStack Table Parsers\ndescription: Store your table state in the URL, with style.\n---\n\n[TanStack Table](http"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/zod-codecs.demo.tsx",
    "chars": 3602,
    "preview": "'use client'\n\nimport { CodeBlock } from '@/src/components/code-block.client'\nimport { QuerySpy } from '@/src/components/"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/zod-codecs.lib.ts",
    "chars": 2610,
    "preview": "import { createParser } from 'nuqs/server'\nimport { z } from 'zod'\n\nfunction createZodCodecParser<\n  Input extends z.Zod"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/zod-codecs.mdx",
    "chars": 1895,
    "preview": "---\ntitle: Zod codecs\ndescription: Using Zod codecs for (de)serialisation in custom nuqs parser\n---\n\nSince `zod@^4.1`, y"
  },
  {
    "path": "packages/docs/content/docs/parsers/community/zod-codecs.skeleton.tsx",
    "chars": 803,
    "preview": "import {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle\n} from '@/src/components/ui/card'\nimport { "
  },
  {
    "path": "packages/docs/content/docs/parsers/community/zod-codecs.source.tsx",
    "chars": 330,
    "preview": "import { CodeBlock } from '@/src/components/code-block'\nimport { readFile } from 'node:fs/promises'\n\nexport async functi"
  },
  {
    "path": "packages/docs/content/docs/parsers/demos.tsx",
    "chars": 22465,
    "preview": "'use client'\n\nimport { CodeBlock } from '@/src/components/code-block.client'\nimport { QuerySpy } from '@/src/components/"
  },
  {
    "path": "packages/docs/content/docs/parsers/making-your-own.mdx",
    "chars": 5091,
    "preview": "---\ntitle: Custom parsers\ndescription: Making your own parsers for custom data types & pretty URLs\n---\n\nimport {\n  Custo"
  },
  {
    "path": "packages/docs/content/docs/parsers/meta.json",
    "chars": 82,
    "preview": "{\n  \"title\": \"Parsers\",\n  \"pages\": [\"built-in\", \"making-your-own\", \"community\"]\n}\n"
  },
  {
    "path": "packages/docs/content/docs/seo.mdx",
    "chars": 2037,
    "preview": "---\ntitle: SEO\ndescription: Pitfalls and best practices for SEO with query strings\n---\n\nIf your page uses query strings "
  },
  {
    "path": "packages/docs/content/docs/server-side.mdx",
    "chars": 9057,
    "preview": "---\ntitle: Server-Side usage\ndescription: Type-safe search params on the server\n---\n\n## Loaders\n\n<FeatureSupportMatrix i"
  },
  {
    "path": "packages/docs/content/docs/testing.mdx",
    "chars": 8087,
    "preview": "---\ntitle: Testing\ndescription: Some tips on testing components that use `nuqs`\n---\n\nSince nuqs 2, you can unit-test com"
  },
  {
    "path": "packages/docs/content/docs/tips-tricks.mdx",
    "chars": 1313,
    "preview": "---\ntitle: Tips and tricks\ndescription: A collection of good practices and tips to help you get the most out of nuqs\n---"
  },
  {
    "path": "packages/docs/content/docs/troubleshooting.mdx",
    "chars": 2369,
    "preview": "---\ntitle: Troubleshooting\ndescription: Common issues and solutions\n---\n\n<Callout title=\"Tip\">\n  Check out the list of ["
  },
  {
    "path": "packages/docs/content/docs/utilities.mdx",
    "chars": 6186,
    "preview": "---\ntitle: Utilities\ndescription: Utilities for working with query strings\n---\n\n## Serializer helper\n\n<FeatureSupportMat"
  },
  {
    "path": "packages/docs/mdx-components.tsx",
    "chars": 1200,
    "preview": "import { HumanContent, LLMContent } from '@/src/components/audience'\nimport { FeatureSupportMatrix } from '@/src/compone"
  },
  {
    "path": "packages/docs/next.config.mjs",
    "chars": 4246,
    "preview": "// @ts-check\n\nimport { withSentryConfig } from '@sentry/nextjs'\nimport { createMDX } from 'fumadocs-mdx/next'\n\nconst wit"
  },
  {
    "path": "packages/docs/package.json",
    "chars": 3069,
    "preview": "{\n  \"name\": \"docs\",\n  \"version\": \"0.0.0-internal\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"author\": {\n    \"name\": \"Fra"
  },
  {
    "path": "packages/docs/public/.well-known/atproto-did",
    "chars": 33,
    "preview": "did:plc:bw4kguuz764ponbbn2aaycxk\n"
  },
  {
    "path": "packages/docs/rehype-code.config.ts",
    "chars": 256,
    "preview": "import type { RehypeCodeOptions } from 'fumadocs-core/mdx-plugins'\n\nexport const rehypeCodeOptions: RehypeCodeOptions = "
  },
  {
    "path": "packages/docs/sentry.edge.config.ts",
    "chars": 965,
    "preview": "// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n// The conf"
  },
  {
    "path": "packages/docs/sentry.server.config.ts",
    "chars": 810,
    "preview": "// This file configures the initialization of Sentry on the server.\n// The config you add here will be used whenever the"
  },
  {
    "path": "packages/docs/source.config.ts",
    "chars": 960,
    "preview": "import {\n  defineCollections,\n  defineConfig,\n  defineDocs,\n  frontmatterSchema\n} from 'fumadocs-mdx/config'\nimport rema"
  },
  {
    "path": "packages/docs/src/app/(llms)/llms/[...slug]/route.tsx",
    "chars": 621,
    "preview": "import { source } from '@/src/app/source'\nimport { getLLMText } from '@/src/lib/get-llm-text'\nimport { notFound } from '"
  },
  {
    "path": "packages/docs/src/app/(llms)/llms-full.txt/route.ts",
    "chars": 1154,
    "preview": "import { fullSource } from '@/src/app/source'\nimport { getLLMText } from '@/src/lib/get-llm-text'\nimport { flattenTree }"
  },
  {
    "path": "packages/docs/src/app/(llms)/llms.txt/route.ts",
    "chars": 1483,
    "preview": "import { fullSource } from '@/src/app/source'\nimport { getBaseUrl } from '@/src/lib/url'\nimport { flattenTree } from 'fu"
  },
  {
    "path": "packages/docs/src/app/(pages)/(confs)/nextjs-conf-25/page.tsx",
    "chars": 2407,
    "preview": "import { LinkTree, type LinkTreeItemProps } from '@/src/components/link-tree'\nimport {\n  SiBluesky,\n  SiGithub,\n  SiTwit"
  },
  {
    "path": "packages/docs/src/app/(pages)/(confs)/react-advanced-25/page.tsx",
    "chars": 2441,
    "preview": "import { LinkTree, type LinkTreeItemProps } from '@/src/components/link-tree'\nimport {\n  SiBluesky,\n  SiGithub,\n  SiTwit"
  },
  {
    "path": "packages/docs/src/app/(pages)/(confs)/react-paris/page.tsx",
    "chars": 2829,
    "preview": "import { Logo47ng } from '@/src/components/47ng'\nimport { LinkTree, type LinkTreeItemProps } from '@/src/components/link"
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/bundle-size.tsx",
    "chars": 657,
    "preview": "import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nfunction prettyBytes(size: number) {\n  const formatter ="
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/contributors.tsx",
    "chars": 4057,
    "preview": "import { cn } from '@/src/lib/utils'\nimport { z } from 'zod'\n\nconst contributorSchema = z.object({\n  login: z.string(),\n"
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/demo.client.tsx",
    "chars": 1553,
    "preview": "'use client'\n\n// [!code word:useQueryState]\nimport { parseAsInteger, useQueryState } from 'nuqs'\n\nexport function Demo()"
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/demo.tsx",
    "chars": 7013,
    "preview": "import { CodeBlock } from '@/src/components/code-block'\nimport fs from 'node:fs/promises'\nimport { format } from 'pretti"
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/dependents.tsx",
    "chars": 22369,
    "preview": "import { cn } from '@/src/lib/utils'\nimport { z } from 'zod'\n\nconst dependentSchema = z.object({\n  stars: z.number(),\n  "
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/features.tsx",
    "chars": 6276,
    "preview": "import {\n  BatteryFull,\n  BookCheck,\n  Feather,\n  History,\n  Hourglass,\n  Link,\n  Rainbow,\n  SatelliteDish,\n  Server,\n  "
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/gha-status.tsx",
    "chars": 2983,
    "preview": "import { cn } from '@/src/lib/utils'\nimport React from 'react'\nimport { z } from 'zod'\n\nexport async function GitHubActi"
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/hero.tsx",
    "chars": 2058,
    "preview": "import { NuqsWordmark } from '@/src/components/logo'\nimport { buttonVariants } from '@/src/components/ui/button'\nimport "
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/page-footer.tsx",
    "chars": 4500,
    "preview": "import { NuqsWordmark } from '@/src/components/logo'\nimport {\n  SiBluesky,\n  SiGithub,\n  SiTwitch,\n  SiX,\n  SiYoutube\n} "
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/quotes/quotes-section.tsx",
    "chars": 14457,
    "preview": "import { Quote } from '@/src/components/quote'\n\nexport function QuotesSection() {\n  return (\n    <section className=\"con"
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/sponsors.tsx",
    "chars": 22126,
    "preview": "import { Button } from '@/src/components/ui/button'\nimport { cn } from '@/src/lib/utils'\nimport { Heart } from 'lucide-r"
  },
  {
    "path": "packages/docs/src/app/(pages)/_landing/works-with.tsx",
    "chars": 583,
    "preview": "import {\n  NextJS,\n  ReactRouter,\n  ReactSPA,\n  Remix,\n  TanStackRouter,\n  Vitest\n} from '@/src/components/frameworks'\ni"
  },
  {
    "path": "packages/docs/src/app/(pages)/blog/[slug]/_components/author.tsx",
    "chars": 543,
    "preview": "export function Author() {\n  return (\n    <a\n      href=\"https://bsky.app/profile/francoisbest.com\"\n      className=\"fle"
  },
  {
    "path": "packages/docs/src/app/(pages)/blog/[slug]/opengraph-image.tsx",
    "chars": 1543,
    "preview": "import { blog } from '@/src/app/source'\nimport { generateOpengraphImage, size } from '@/src/components/og-image'\nimport "
  },
  {
    "path": "packages/docs/src/app/(pages)/blog/[slug]/page.tsx",
    "chars": 4326,
    "preview": "import { blog } from '@/src/app/source'\n// import { createMetadata } from '@/utils/metadata'\nimport { PageFooter } from "
  },
  {
    "path": "packages/docs/src/app/(pages)/blog/[slug]/twitter-image.tsx",
    "chars": 152,
    "preview": "import Image from './opengraph-image'\nexport default Image\nexport { contentType, size } from './opengraph-image'\n\nexport"
  },
  {
    "path": "packages/docs/src/app/(pages)/blog/_lib/source.ts",
    "chars": 295,
    "preview": "import { blog } from '@/src/app/source'\n\nexport type BlogPost = ReturnType<typeof blog.getPages>[number]\n\nexport functio"
  },
  {
    "path": "packages/docs/src/app/(pages)/blog/page.tsx",
    "chars": 3182,
    "preview": "import { blog } from '@/src/app/source'\nimport {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  B"
  },
  {
    "path": "packages/docs/src/app/(pages)/blog/rss.xml/route.ts",
    "chars": 1106,
    "preview": "import { getBlogPosts } from '../_lib/source'\n\nexport const dynamic = 'force-static'\n\nexport async function GET() {\n  co"
  },
  {
    "path": "packages/docs/src/app/(pages)/layout.tsx",
    "chars": 286,
    "preview": "import { getSharedLayoutProps } from '@/src/components/shared-layout'\nimport { HomeLayout } from 'fumadocs-ui/layouts/ho"
  },
  {
    "path": "packages/docs/src/app/(pages)/page.tsx",
    "chars": 1008,
    "preview": "import type { Metadata } from 'next'\nimport { metadata as rootMetadata } from '../layout'\nimport { ContributorsSection }"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/downloads.client.tsx",
    "chars": 4587,
    "preview": "'use client'\n\nimport {\n  ChartContainer,\n  ChartLegend,\n  ChartLegendContent,\n  ChartTooltip,\n  ChartTooltipContent\n} fr"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/downloads.tsx",
    "chars": 8023,
    "preview": "import { Badge } from '@/src/components/ui/badge'\nimport { cn } from '@/src/lib/utils'\nimport { Download, Minus, Trendin"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/graph.skeleton.tsx",
    "chars": 397,
    "preview": "import { cn } from '@/src/lib/utils'\nimport { ComponentProps } from 'react'\n\nexport function GraphSkeleton({ className }"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/partial-line.tsx",
    "chars": 6993,
    "preview": "'use client'\n\nimport { Line, LineProps, usePlotArea, useYAxisScale } from 'recharts'\n\nfunction clamp(value: number, min:"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/stars.client.tsx",
    "chars": 3877,
    "preview": "'use client'\n\nimport {\n  ChartContainer,\n  ChartTooltip,\n  ChartTooltipContent\n} from '@/src/components/ui/chart'\nimport"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/stars.gazers-list.tsx",
    "chars": 2711,
    "preview": "import { cn } from '@/src/lib/utils'\nimport { formatDate, formatStatNumber } from '../lib/format'\nimport type { GitHubSt"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/stars.tsx",
    "chars": 960,
    "preview": "import { Star } from 'lucide-react'\nimport { connection } from 'next/server'\nimport { getStarHistory } from '../lib/gith"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/versions.tsx",
    "chars": 4759,
    "preview": "'use client'\n\nimport {\n  ChartContainer,\n  ChartLegend,\n  ChartLegendContent,\n  ChartTooltip,\n  ChartTooltipContent\n} fr"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/widget.skeleton.tsx",
    "chars": 232,
    "preview": "import { cn } from '@/src/lib/utils'\nimport { Widget, WidgetProps } from './widget'\n\nexport function WidgetSkeleton({ cl"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/_components/widget.tsx",
    "chars": 552,
    "preview": "import { cn } from '@/src/lib/utils'\nimport type { ComponentProps, ReactNode } from 'react'\n\nexport type WidgetProps = O"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/lib/format.ts",
    "chars": 1260,
    "preview": "const LOCALE = 'en-GB'\n\n/**\n * Format a date-ish object to a locale-friendly string\n */\nexport function formatDate(\n  da"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/lib/github.ts",
    "chars": 4767,
    "preview": "import dayjs from 'dayjs'\nimport utc from 'dayjs/plugin/utc'\nimport 'server-only'\nimport { z } from 'zod'\n\ndayjs.extend("
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/lib/npm.ts",
    "chars": 7419,
    "preview": "import dayjs from 'dayjs'\nimport isoWeek from 'dayjs/plugin/isoWeek'\nimport minMax from 'dayjs/plugin/minMax'\nimport 'se"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/lib/svg.ts",
    "chars": 2191,
    "preview": "// Source:\n// https://medium.com/@francoisromain/smooth-a-svg-path-with-cubic-bezier-curves-e37b49d46c74\n\nexport type Po"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/lib/versions.ts",
    "chars": 91577,
    "preview": "import 'server-only'\nimport { z } from 'zod'\n\nconst versionsData = `\n{\"date\":\"2025-09-01\",\"package\":\"next-usequerystate\""
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/page.tsx",
    "chars": 2539,
    "preview": "import { SearchParams } from 'nuqs/server'\nimport { Suspense } from 'react'\nimport {\n  NPMDownloads,\n  NPMDownloadsSkele"
  },
  {
    "path": "packages/docs/src/app/(pages)/stats/searchParams.ts",
    "chars": 387,
    "preview": "import { createLoader, parseAsBoolean, parseAsStringLiteral } from 'nuqs/server'\n\nexport const pkgOptions = ['nuqs', 'ne"
  },
  {
    "path": "packages/docs/src/app/(pages)/users/page.tsx",
    "chars": 2483,
    "preview": "import { Description, H1 } from '@/src/components/typography'\nimport { cn } from '@/src/lib/utils'\nimport { Star } from "
  },
  {
    "path": "packages/docs/src/app/api/isr/.gitignore",
    "chars": 16,
    "preview": "invalidate-*.sh\n"
  },
  {
    "path": "packages/docs/src/app/api/isr/route.ts",
    "chars": 770,
    "preview": "import { revalidateTag } from 'next/cache'\nimport { NextRequest, NextResponse } from 'next/server'\n\nconst ACCEPTED_TAGS "
  },
  {
    "path": "packages/docs/src/app/api/search/route.ts",
    "chars": 467,
    "preview": "import { source, type Page } from '@/src/app/source'\nimport { createSearchAPI } from 'fumadocs-core/search/server'\n\nexpo"
  },
  {
    "path": "packages/docs/src/app/banners.tsx",
    "chars": 53447,
    "preview": "import { Banner } from 'fumadocs-ui/components/banner'\nimport { PlayIcon } from 'lucide-react'\nimport Link from 'next/li"
  },
  {
    "path": "packages/docs/src/app/docs/[[...slug]]/page.tsx",
    "chars": 3091,
    "preview": "import { useMDXComponents } from '@/mdx-components'\nimport { AsideSponsors } from '@/src/app/(pages)/_landing/sponsors'\n"
  },
  {
    "path": "packages/docs/src/app/docs/layout.tsx",
    "chars": 792,
    "preview": "import { source } from '@/src/app/source'\nimport { getSharedLayoutProps } from '@/src/components/shared-layout'\nimport {"
  },
  {
    "path": "packages/docs/src/app/global-error.tsx",
    "chars": 509,
    "preview": "'use client'\n\nimport * as Sentry from '@sentry/nextjs'\nimport Error from 'next/error'\nimport { useEffect } from 'react'\n"
  },
  {
    "path": "packages/docs/src/app/globals.css",
    "chars": 3803,
    "preview": "@import 'tailwindcss';\n@import 'fumadocs-ui/css/black.css';\n@import 'fumadocs-ui/css/preset.css';\n@import './styles/twea"
  },
  {
    "path": "packages/docs/src/app/layout.tsx",
    "chars": 2387,
    "preview": "import { Databuddy } from '@databuddy/sdk/react'\nimport * as Sentry from '@sentry/nextjs'\nimport { RootProvider } from '"
  },
  {
    "path": "packages/docs/src/app/not-found.tsx",
    "chars": 1561,
    "preview": "import { Button } from '../components/ui/button'\nimport PageLayout from './(pages)/layout'\n\nexport default function NotF"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/_components/source-on-github.tsx",
    "chars": 1535,
    "preview": "import { CodeBlock } from '@/src/components/code-block'\nimport * as Sentry from '@sentry/nextjs'\nimport { FileCode2 } fr"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/basic-counter/client.tsx",
    "chars": 779,
    "preview": "'use client'\n\nimport { Button } from '@/src/components/ui/button'\nimport { Minus, Plus } from 'lucide-react'\nimport { pa"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/basic-counter/page.tsx",
    "chars": 644,
    "preview": "import { Description, H1 } from '@/src/components/typography'\nimport { Suspense } from 'react'\nimport { SourceOnGitHub }"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/batching/client.tsx",
    "chars": 1013,
    "preview": "'use client'\n\nimport { Button } from '@/src/components/ui/button'\nimport { parseAsFloat, useQueryState } from 'nuqs'\n\nco"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/batching/page.tsx",
    "chars": 552,
    "preview": "import { Description } from '@/src/components/typography'\nimport { Suspense } from 'react'\nimport { SourceOnGitHub } fro"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/demos.ts",
    "chars": 1200,
    "preview": "import type * as PageTree from 'fumadocs-core/page-tree'\n\ntype DemoMetadata = {\n  title: string\n  description: string\n}\n"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/hex-colors/client.tsx",
    "chars": 2852,
    "preview": "'use client'\n\nimport { createParser, parseAsHex, useQueryState } from 'nuqs'\n\nconst hexColorSchema = createParser({\n  pa"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/hex-colors/page.tsx",
    "chars": 551,
    "preview": "import { Description } from '@/src/components/typography'\nimport { Suspense } from 'react'\nimport { SourceOnGitHub } fro"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/layout.tsx",
    "chars": 424,
    "preview": "import { QuerySpy } from '@/src/components/query-spy'\nimport { QuerystringSkeleton } from '@/src/components/querystring'"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/pagination/api.ts",
    "chars": 703,
    "preview": "import { faker } from '@faker-js/faker'\n\n// Ensure consistent results\nfaker.seed(47)\n\nexport const pageSize = 5\nexport c"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/pagination/page.tsx",
    "chars": 2828,
    "preview": "import { Description } from '@/src/components/typography'\nimport { Separator } from '@/src/components/ui/separator'\nimpo"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/pagination/pagination-controls.client.tsx",
    "chars": 1724,
    "preview": "'use client'\n\nimport {\n  Pagination,\n  PaginationButton,\n  PaginationContent,\n  PaginationItem,\n  PaginationNext,\n  Pagi"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/pagination/pagination-controls.server.tsx",
    "chars": 1743,
    "preview": "import {\n  Pagination,\n  PaginationContent,\n  PaginationItem,\n  PaginationLink,\n  PaginationNextLink,\n  PaginationPrevio"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/pagination/product.tsx",
    "chars": 534,
    "preview": "import type { Product } from './api'\n\ntype ProductViewProps = React.ComponentProps<'div'> & {\n  product: Product\n}\n\nexpo"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/pagination/rendering-controls.tsx",
    "chars": 2141,
    "preview": "'use client'\n\nimport { Label } from '@/src/components/ui/label'\nimport { ToggleGroup, ToggleGroupItem } from '@/src/comp"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/pagination/search-params.ts",
    "chars": 946,
    "preview": "import { useQueryState, useQueryStates } from 'nuqs'\nimport {\n  createLoader,\n  createSerializer,\n  type inferParserType"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/tic-tac-toe/client.tsx",
    "chars": 4394,
    "preview": "'use client'\n\nimport { Button } from '@/src/components/ui/button'\nimport { cn } from '@/src/lib/utils'\nimport { createPa"
  },
  {
    "path": "packages/docs/src/app/playground/(demos)/tic-tac-toe/page.tsx",
    "chars": 629,
    "preview": "import { Description } from '@/src/components/typography'\nimport { Suspense } from 'react'\nimport { SourceOnGitHub } fro"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/builder-pattern/page.tsx",
    "chars": 936,
    "preview": "'use client'\n\nimport { parseAsInteger, useQueryState } from 'nuqs'\n\nexport default function BuilderPatternDemoPage() {\n "
  },
  {
    "path": "packages/docs/src/app/playground/_demos/compound-parsers/page.tsx",
    "chars": 1868,
    "preview": "'use client'\n\nimport { parseAsArrayOf, parseAsJson, useQueryState } from 'nuqs'\n\nconst escaped = '-_.!~*\\'()?#/&,\"`<>{}["
  },
  {
    "path": "packages/docs/src/app/playground/_demos/crosslink/page.tsx",
    "chars": 1820,
    "preview": "'use client'\n\nimport Link from 'next/link'\nimport { parseAsString, useQueryState, useQueryStates } from 'nuqs'\n\nconst pa"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/custom-parser/page.tsx",
    "chars": 2630,
    "preview": "'use client'\n\nimport { createParser, useQueryState } from 'nuqs'\n\ntype SortingState = Record<string, 'asc' | 'desc'>\n\nco"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/parsers/page.tsx",
    "chars": 3730,
    "preview": "'use client'\n\nimport {\n  parseAsArrayOf,\n  parseAsBoolean,\n  parseAsFloat,\n  parseAsHex,\n  parseAsInteger,\n  parseAsIsoD"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/pretty-urls/page.tsx",
    "chars": 1061,
    "preview": "'use client'\n\nimport { useQueryState } from 'nuqs'\n\nconst testValues = [\n  '/home/user/.ssh/id.pub',\n  '192.168.0.0',\n  "
  },
  {
    "path": "packages/docs/src/app/playground/_demos/repro-359/page.tsx",
    "chars": 2594,
    "preview": "// https://github.com/47ng/nuqs/issues/359\n\n'use client'\n\nimport {\n  parseAsString,\n  parseAsStringEnum,\n  useQueryState"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/repro-376/page.tsx",
    "chars": 1201,
    "preview": "'use client'\n\nimport { useQueryState } from 'nuqs'\n\nexport default function ReproPage() {\n  const [searchQueryUrl, setSe"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/repro-907/page.tsx",
    "chars": 1321,
    "preview": "// https://github.com/47ng/nuqs/issues/907\n\n'use client'\n\nimport { parseAsString, useQueryStates } from 'nuqs'\nimport { "
  },
  {
    "path": "packages/docs/src/app/playground/_demos/server-side-parsing/client.tsx",
    "chars": 1738,
    "preview": "'use client'\n\nimport { parseAsBoolean, useQueryState } from 'nuqs'\nimport { counterParser } from './parser'\n\ntype Props "
  },
  {
    "path": "packages/docs/src/app/playground/_demos/server-side-parsing/page.tsx",
    "chars": 851,
    "preview": "import { Suspense } from 'react'\nimport { ServerSideParsingDemoClient } from './client'\nimport { counterParser } from '."
  },
  {
    "path": "packages/docs/src/app/playground/_demos/server-side-parsing/parser.ts",
    "chars": 105,
    "preview": "import { parseAsInteger } from 'nuqs/server'\n\nexport const counterParser = parseAsInteger.withDefault(0)\n"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/throttling/client.tsx",
    "chars": 3455,
    "preview": "'use client'\n\nimport { useRouter } from 'next/navigation'\nimport { useQueryState } from 'nuqs'\nimport React from 'react'"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/throttling/page.tsx",
    "chars": 1285,
    "preview": "import { setTimeout } from 'node:timers/promises'\nimport { Suspense } from 'react'\nimport { Client } from './client'\nimp"
  },
  {
    "path": "packages/docs/src/app/playground/_demos/throttling/parsers.ts",
    "chars": 175,
    "preview": "import { parseAsInteger, parseAsString } from 'nuqs/server'\n\nexport const delayParser = parseAsInteger.withDefault(0)\nex"
  },
  {
    "path": "packages/docs/src/app/playground/debug-control.tsx",
    "chars": 815,
    "preview": "'use client'\n\nimport React from 'react'\n\nexport function DebugControl() {\n  const [checked, setChecked] = React.useState"
  },
  {
    "path": "packages/docs/src/app/playground/layout.tsx",
    "chars": 1086,
    "preview": "import { getSharedLayoutProps } from '@/src/components/shared-layout'\nimport { DocsLayout } from 'fumadocs-ui/layouts/no"
  },
  {
    "path": "packages/docs/src/app/playground/page.tsx",
    "chars": 883,
    "preview": "import { Card } from 'fumadocs-ui/components/card'\nimport {\n  DocsBody,\n  DocsDescription,\n  DocsPage,\n  DocsTitle\n} fro"
  },
  {
    "path": "packages/docs/src/app/registry/[name]/author.tsx",
    "chars": 775,
    "preview": "import { authorRegex } from '@/src/registry/schemas'\n\nexport function Author({ author }: { author: string }) {\n  const ["
  },
  {
    "path": "packages/docs/src/app/registry/[name]/opengraph-image.tsx",
    "chars": 876,
    "preview": "import { generateOpengraphImage } from '@/src/components/og-image'\nimport { readRegistry, readRegistryItem } from '@/src"
  },
  {
    "path": "packages/docs/src/app/registry/[name]/page.tsx",
    "chars": 4272,
    "preview": "import { useMDXComponents } from '@/mdx-components'\nimport { rehypeCodeOptions } from '@/rehype-code.config'\nimport { Co"
  },
  {
    "path": "packages/docs/src/app/registry/[name]/twitter-image.tsx",
    "chars": 152,
    "preview": "import Image from './opengraph-image'\nexport default Image\nexport { contentType, size } from './opengraph-image'\n\nexport"
  },
  {
    "path": "packages/docs/src/app/registry/layout.tsx",
    "chars": 3065,
    "preview": "import { getSharedLayoutProps } from '@/src/components/shared-layout'\nimport { SidebarFooter } from '@/src/components/si"
  },
  {
    "path": "packages/docs/src/app/registry/page.tsx",
    "chars": 7816,
    "preview": "import { H2 } from '@/src/components/typography'\nimport { Card, Cards } from 'fumadocs-ui/components/card'\nimport {\n  Do"
  },
  {
    "path": "packages/docs/src/app/registry/rss.xml/route.ts",
    "chars": 1426,
    "preview": "import { getLastModified } from '@/src/lib/get-last-modified'\nimport { readRegistry } from '@/src/registry/read'\nimport "
  },
  {
    "path": "packages/docs/src/app/robots.ts",
    "chars": 549,
    "preview": "import { getBaseUrl } from '@/src/lib/url'\nimport type { MetadataRoute } from 'next'\n\nexport default function robots(): "
  },
  {
    "path": "packages/docs/src/app/sitemap.ts",
    "chars": 2333,
    "preview": "import { getLastModified } from '@/src/lib/get-last-modified'\nimport { getBaseUrl } from '@/src/lib/url'\nimport type { M"
  },
  {
    "path": "packages/docs/src/app/source.ts",
    "chars": 1123,
    "preview": "import { blog as blogPosts, docs, meta } from '@/.source'\nimport type { Item } from 'fumadocs-core/page-tree'\nimport { t"
  },
  {
    "path": "packages/docs/src/app/styles/tweaks.css",
    "chars": 1773,
    "preview": "@layer utilities {\n  /* Background & line spacing for code blocks */\n  /* eg: The demo code block on the landing page */"
  },
  {
    "path": "packages/docs/src/components/47ng.tsx",
    "chars": 3128,
    "preview": "import { cn } from '@/src/lib/utils'\nimport React from 'react'\n\nconst sizes = {\n  6: 'w-6 h-6',\n  8: 'w-8 h-8',\n  16: 'w"
  },
  {
    "path": "packages/docs/src/components/ai/page-actions.tsx",
    "chars": 11928,
    "preview": "// Full credits to fumadocs (https://www.fumadocs.dev/) for this component!\n\n'use client'\n\nimport { cn } from '@/src/lib"
  },
  {
    "path": "packages/docs/src/components/audience.tsx",
    "chars": 529,
    "preview": "import type { ReactNode } from 'react'\n\ntype AudienceProps = {\n  children?: ReactNode\n}\n\n/**\n * Content that is only sho"
  },
  {
    "path": "packages/docs/src/components/code-block-defs.ts",
    "chars": 350,
    "preview": "import type { CodeBlockProps as FumaDocsCodeBlockProps } from 'fumadocs-ui/components/codeblock'\nimport type { BundledLa"
  },
  {
    "path": "packages/docs/src/components/code-block-highlighter.skeleton.ts",
    "chars": 181,
    "preview": "export function renderCodeSkeleton(code: string) {\n  return `<pre><code>${code\n    .split('\\n')\n    .map(line => `<span "
  },
  {
    "path": "packages/docs/src/components/code-block-highlighter.ts",
    "chars": 778,
    "preview": "import { rehypeCodeOptions } from '@/rehype-code.config'\nimport {\n  transformerNotationHighlight,\n  transformerNotationW"
  },
  {
    "path": "packages/docs/src/components/code-block.client.tsx",
    "chars": 1194,
    "preview": "'use client'\n\nimport {\n  CodeBlock as FumaDocsCodeBlock,\n  Pre\n} from 'fumadocs-ui/components/codeblock'\nimport { use, u"
  },
  {
    "path": "packages/docs/src/components/code-block.tsx",
    "chars": 635,
    "preview": "import {\n  CodeBlock as FumaDocsCodeBlock,\n  Pre\n} from 'fumadocs-ui/components/codeblock'\nimport type { CodeBlockProps "
  },
  {
    "path": "packages/docs/src/components/countdown.tsx",
    "chars": 2736,
    "preview": "'use client'\n\nimport { cn } from '@/src/lib/utils'\nimport NumberFlow, { NumberFlowGroup } from '@number-flow/react'\nimpo"
  },
  {
    "path": "packages/docs/src/components/favicon.tsx",
    "chars": 316,
    "preview": "export function Favicon() {\n  const env = process.env.VERCEL_ENV ?? process.env.NODE_ENV ?? 'development'\n  const isDev "
  }
]

// ... and 940 more files (download for full content)

About this extraction

This page contains the full source code of the 47ng/nuqs GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1140 files (1.6 MB), approximately 568.3k tokens, and a symbol index with 1224 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!