Provides setup and API documentation for managing URL query state in Next.js projects using nuqs.
Install
mkdir -p .claude/skills/nuqs-marlanperumal && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/12317" && unzip -o skill.zip -d .claude/skills/nuqs-marlanperumal && rm skill.zipInstalls to .claude/skills/nuqs-marlanperumal
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Install: `just add-web-dep nuqs`Key capabilities
- →Sync component state with URL query parameters
- →Parse query parameters as various types (integer, string, boolean)
- →Batch URL writes for multiple parameter updates
- →Set default values for query parameters
- →Configure history and scroll behavior for URL changes
- →Use `parseAsJson` for complex nested data
How it works
The skill provides hooks and parsers to synchronize component state with URL query parameters. It allows defining single or multiple parameters, parsing them into various types, and configuring URL update behavior.
Inputs & outputs
When to use nuqs
- →Managing search filters in URL
- →Syncing state with query params
- →Handling URL state in Next.js
- →Parsing URL search parameters
About this skill
nuqs — URL Query State (v2.x, Next.js App Router)
Setup
Install: just add-web-dep nuqs
Wrap the root layout body with NuqsAdapter (server component, no 'use client' needed):
// apps/web/src/app/layout.tsx
import { NuqsAdapter } from 'nuqs/adapters/next/app'
export default function RootLayout({ children }) {
return (
<html>
<body>
<NuqsAdapter>{children}</NuqsAdapter>
</body>
</html>
)
}
Core API
Single param
import { useQueryState, parseAsInteger } from 'nuqs'
const [page, setPage] = useQueryState('page', parseAsInteger.withDefault(1))
Multiple params (preferred — batches URL writes)
import { useQueryStates, parseAsString, parseAsInteger, parseAsStringLiteral } from 'nuqs'
const [params, setParams] = useQueryStates(
{
mode: parseAsStringLiteral(['crosstab', 'trend'] as const).withDefault('crosstab'),
ds: parseAsInteger, // null when absent
q: parseAsString, // null when absent
},
{ history: 'replace', scroll: false }
)
// Partial update — only specified keys change
setParams({ mode: 'trend' })
Built-in Parsers
| Parser | Type | Notes |
|---|---|---|
parseAsString | string | null | no-op, any value |
parseAsInteger | number | null | parseInt base 10 |
parseAsFloat | number | null | parseFloat |
parseAsBoolean | boolean | null | |
parseAsStringLiteral(['a','b'] as const) | 'a' | 'b' | null | validates against list |
parseAsArrayOf(parseAsString) | string[] | null | comma-separated by default |
parseAsJson<T>((v) => v as T) | T | null | JSON encode/decode; requires a validator function (breaking change in newer nuqs) |
parseAsIsoDateTime | Date | null | ISO 8601 |
All parsers support .withDefault(value) to replace null with a default, and .withOptions({...}) for per-param options.
Options
| Option | Default | Description |
|---|---|---|
history | 'replace' | 'replace' or 'push' (adds browser history entry) |
scroll | false | scroll to top on change |
shallow | true | set false to notify server (re-renders Server Components) |
clearOnDefault | true | omit param from URL when value equals default |
Options can be set globally via <NuqsAdapter defaultOptions={...}> or per-hook as the second argument.
Project Convention
This project wraps a QueryConfig domain type in a thin hook (useAnalyticsState) that maps between QueryConfig and flat URL params. Keep this pattern: domain types stay in analytics-types.ts, URL mapping lives in the hook.
URL key shorthand — use short keys (ds, col, bd, mt, md) via useQueryStates with the urlKeys option, or just name them directly. Short keys keep URLs legible.
Complex nested data (e.g. filters with levels) — use parseAsJson<T>((v) => v as T) rather than flattening. The validator is required; a simple cast is fine if you trust the URL source.
Storybook
Use NuqsTestingAdapter from nuqs/adapters/testing — not the next/app adapter.
The next/app adapter calls useRouter() internally and throws
invariant expected app router to be mounted because Storybook doesn't mount the
Next.js App Router. NuqsTestingAdapter is a self-contained in-memory URL store
that works in any non-router environment.
// AnalyticsPage.stories.tsx
import { NuqsTestingAdapter } from "nuqs/adapters/testing"
const meta = {
decorators: [
(Story) => (
<NuqsTestingAdapter>
<Story />
</NuqsTestingAdapter>
),
],
} satisfies Meta<typeof MyComponent>
Testing
Mock only useQueryStates, let real parsers run (they're pure functions):
vi.mock('nuqs', async (importActual) => {
const actual = await importActual<typeof import('nuqs')>()
return { ...actual, useQueryStates: vi.fn() }
})
beforeEach(() => {
vi.mocked(useQueryStates).mockReturnValue([defaultParams, mockSetP])
})
When not to use it
- →When not using Next.js App Router
- →When using `useRouter()` in Storybook without `NuqsTestingAdapter`
Limitations
- →Requires `NuqsAdapter` to wrap the root layout body
- →Requires `NuqsTestingAdapter` for Storybook environments
- →The `parseAsJson` validator is required for complex nested data
How it compares
This skill offers a structured and type-safe way to manage URL query state in Next.js App Router applications, simplifying the synchronization of component state with the URL compared to manual URL manipulation.
Compared to similar skills
nuqs side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| nuqs (this skill) | 0 | 3mo | No flags | Beginner |
| ai-model-web | 1 | 2mo | Review | Intermediate |
| rdc-setup | 1 | 5mo | Review | Intermediate |
| tanstack-query-expert | 0 | 3mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
ai-model-web
TencentCloudBase
Use this skill when developing browser/Web applications (React/Vue/Angular, static websites, SPAs) that need AI capabilities. Features text generation (generateText) and streaming (streamText) via @cloudbase/js-sdk. Built-in models include Hunyuan (hunyuan-2.0-instruct-20251111 recommended) and DeepSeek (deepseek-v3.2 recommended). NOT for Node.js backend (use ai-model-nodejs), WeChat Mini Program (use ai-model-wechat), or image generation (Node SDK only).
rdc-setup
reactive
Install and set up @data-client/react or @data-client/vue in a project. Detects project type (NextJS, Expo, React Native, Vue, plain React) and protocol (REST, GraphQL, custom), then hands off to protocol-specific setup skills.
tanstack-query-expert
Anhvu1107
ALWAYS use this when the request matches Tanstack Query Expert: Expert in TanStack Query (React Query) — asynchronous state management.
algolia-search
aiskillstore
Expert patterns for Algolia search implementation, indexing strategies, React InstantSearch, and relevance tuning Use when: adding search to, algolia, instantsearch, search api, search functionality.
hr-portal-skill
hariventures2000-ship-it
Use this skill when developing, testing, debugging, or modifying code inside the HR Portal frontend (apps/hr-portal). It applies to handling HR administration tasks such as employee roster management, contract seeding, leave request approvals, attendance monitoring, payroll calculation, and recruitm
dapp
salazarsebas
Stellar dApp / frontend development. Covers the JavaScript stellar-sdk (browser + Node.js), Freighter wallet, Stellar Wallets Kit (multi-wallet), Wallet Standard, smart accounts with passkeys, transaction building / signing / submission, Soroban contract invocation from the client, simulation, and e