This page documents all major TypeScript types exported by nuqs. These types help you build type-safe applications with full IntelliSense support.
Options Types
Options
The main options object for configuring URL updates and navigation behavior.
type Options = {
/**
* How the query update affects page history
*
* `push` will create a new history entry, allowing to use the back/forward
* buttons to navigate state updates.
* `replace` (default) will keep the current history point and only replace
* the query string.
*/
history?: HistoryOptions
/**
* Scroll to top after a query state update
*
* Defaults to `false`, unlike the Next.js router page navigation methods.
*/
scroll?: boolean
/**
* Shallow mode (true by default) keeps query states update client-side only,
* meaning there won't be calls to the server.
*
* Setting it to `false` will trigger a network request to the server with
* the updated querystring.
*/
shallow?: boolean
/**
* Limit the rate of URL updates to prevent spamming the browser history,
* and the server if `shallow: false`.
*
* This is to alleviate rate-limiting of the Web History API in browsers,
* and defaults to 50ms. Safari requires a higher value of around 120ms.
*
* Note: the value will be limited to a minimum of 50ms, anything lower
* will not have any effect.
*/
limitUrlUpdates?: LimitUrlUpdates
/**
* In RSC frameworks, opt-in to observing Server Component loading states when
* doing non-shallow updates by passing a `startTransition` from the
* `React.useTransition()` hook.
*
* In other frameworks, navigation events triggered by a query update can also
* be wrapped in a transition this way (e.g. `React.startTransition`).
*/
startTransition?: TransitionStartFunction
/**
* Clear the key-value pair from the URL query string when setting the state
* to the default value.
*
* Defaults to `true` to keep URLs clean.
*
* Set it to `false` to keep backwards-compatiblity when the default value
* changes (prefer explicit URLs whose meaning don't change).
*/
clearOnDefault?: boolean
}
Usage:
import { useQueryState, parseAsInteger } from 'nuqs'
function Component() {
const [count, setCount] = useQueryState(
'count',
parseAsInteger.withOptions({
history: 'push',
scroll: false,
shallow: true,
clearOnDefault: true
})
)
// Or pass options to individual updates
const increment = () => setCount(c => c + 1, { history: 'push' })
}
HistoryOptions
Controls how URL updates affect browser history.
type HistoryOptions = 'replace' | 'push'
'replace' (default): Updates the current history entry
'push': Creates a new history entry (enables back/forward navigation)
LimitUrlUpdates
Configuration for rate-limiting URL updates.
type LimitUrlUpdates =
| { method: 'debounce'; timeMs: number }
| { method: 'throttle'; timeMs: number }
Usage:
import { useQueryState, parseAsString, throttle, debounce } from 'nuqs'
// Using the helper functions
const [search, setSearch] = useQueryState(
'q',
parseAsString.withOptions({
limitUrlUpdates: throttle(100) // Update URL at most every 100ms
})
)
// Using the object form
const [query, setQuery] = useQueryState(
'query',
parseAsString.withOptions({
limitUrlUpdates: { method: 'debounce', timeMs: 300 }
})
)
SearchParams
Type representing URL search parameters as an object.
type SearchParams = Record<string, string | string[] | undefined>
Usage:
import type { SearchParams } from 'nuqs'
// Next.js App Router
type PageProps = {
searchParams: SearchParams
}
export default function Page({ searchParams }: PageProps) {
// searchParams.tag could be string, string[], or undefined
const tag = searchParams.tag
}
Parser Types
SingleParser
Defines a parser for single-value query parameters.
type SingleParser<T> = {
type?: 'single'
/**
* Convert a query string value into a state value.
*
* If the string value does not represent a valid state value,
* the parser should return `null`. Throwing an error is also supported.
*/
parse: (value: string) => T | null
/**
* Render the state value into a query string value.
*/
serialize?: (value: T) => string
/**
* Check if two state values are equal.
*
* This is used when using the `clearOnDefault` value, to compare the default
* value with the set value.
*
* It makes sense to provide this function when the state value is an object
* or an array, as the default referential equality check will not work.
*/
eq?: (a: T, b: T) => boolean
}
Usage:
import { createParser } from 'nuqs'
const parseAsColor = createParser<string>({
parse: (value) => {
// Validate color hex code
if (/^#[0-9A-F]{6}$/i.test(value)) {
return value
}
return null
},
serialize: (value) => value
})
MultiParser
Defines a parser for multi-value query parameters (e.g., ?tag=a&tag=b).
type MultiParser<T> = {
type: 'multi'
parse: (value: ReadonlyArray<string>) => T | null
serialize?: (value: T) => Array<string>
eq?: (a: T, b: T) => boolean
}
Usage:
import { createMultiParser } from 'nuqs'
const parseAsTags = createMultiParser<string[]>({
parse: (values) => values.length > 0 ? values : null,
serialize: (values) => values
})
SingleParserBuilder
Enhanced parser with builder methods for setting defaults and options.
type SingleParserBuilder<T> = Required<SingleParser<T>> & Options & {
/**
* Set history type, shallow routing and scroll restoration options
* at the hook declaration level.
*/
withOptions<This>(this: This, options: Options): This
/**
* Specifying a default value makes the hook state non-nullable when the
* query is missing from the URL: the default value is returned instead
* of `null`.
*/
withDefault(
this: SingleParserBuilder<T>,
defaultValue: NonNullable<T>
): Omit<SingleParserBuilder<T>, 'parseServerSide'> & {
readonly defaultValue: NonNullable<T>
}
}
Usage:
import { parseAsInteger } from 'nuqs'
// Chain builder methods
const pageParser = parseAsInteger
.withDefault(1)
.withOptions({ history: 'push' })
const [page, setPage] = useQueryState('page', pageParser)
// page is number (never null due to default)
GenericParser
Union type for single or multi parsers.
type GenericParser<T> = SingleParser<T> | MultiParser<T>
GenericParserBuilder
Union type for parser builders.
type GenericParserBuilder<T> = SingleParserBuilder<T> | MultiParserBuilder<T>
ParserMap
Object mapping keys to parsers, used with useQueryStates.
type ParserMap = Record<string, ParserWithOptionalDefault<any>>
type ParserWithOptionalDefault<T> = GenericParserBuilder<T> & {
defaultValue?: T
}
Usage:
import { useQueryStates, parseAsInteger, parseAsString } from 'nuqs'
const parsers = {
page: parseAsInteger.withDefault(1),
search: parseAsString,
sort: parseAsStringLiteral(['asc', 'desc'] as const).withDefault('asc')
} satisfies ParserMap
const [{ page, search, sort }, setAll] = useQueryStates(parsers)
Hook Return Types
UseQueryStateReturn
Return type for the useQueryState hook.
type UseQueryStateReturn<Parsed, Default> = [
Default extends undefined
? Parsed | null // value can be null if no default
: Parsed, // value is non-nullable with default
(
value:
| null
| Parsed
| ((old: Default extends Parsed ? Parsed : Parsed | null) => Parsed | null),
options?: Options
) => Promise<URLSearchParams>
]
Usage:
import { useQueryState, parseAsInteger } from 'nuqs'
// Without default - state can be null
const [count, setCount] = useQueryState('count', parseAsInteger)
// ^? number | null
// With default - state is never null
const [page, setPage] = useQueryState('page', parseAsInteger.withDefault(1))
// ^? number
// Setter accepts value, updater function, or null
setCount(42)
setCount(old => old ? old + 1 : 1)
setCount(null) // Clear from URL
UseQueryStatesReturn
Return type for the useQueryStates hook.
type UseQueryStatesReturn<T extends UseQueryStatesKeysMap> = [
Values<T>,
SetValues<T>
]
type Values<T extends UseQueryStatesKeysMap> = {
[K in keyof T]: T[K]['defaultValue'] extends NonNullable<ReturnType<T[K]['parse']>>
? NonNullable<ReturnType<T[K]['parse']>>
: ReturnType<T[K]['parse']> | null
}
type SetValues<T extends UseQueryStatesKeysMap> = (
values: Partial<Nullable<Values<T>>> | UpdaterFn<T> | null,
options?: Options
) => Promise<URLSearchParams>
Usage:
import { useQueryStates, parseAsInteger, parseAsString } from 'nuqs'
const [state, setState] = useQueryStates({
page: parseAsInteger.withDefault(1),
search: parseAsString
})
// State is inferred correctly
state.page // number
state.search // string | null
// Update single or multiple values
setState({ page: 2 })
setState({ page: 2, search: 'query' })
setState(old => ({ page: old.page + 1 }))
setState(null) // Clear all
Utility Types
inferParserType
Type helper to extract the returned data type from a parser or parser map.
type inferParserType<Input> =
Input extends GenericParserBuilder<any>
? inferSingleParserType<Input>
: Input extends Record<string, GenericParserBuilder<any>>
? inferParserRecordType<Input>
: never
Usage:
import { parseAsInteger, parseAsBoolean, type inferParserType } from 'nuqs'
// Single parser
const intParser = parseAsInteger
type IntType = inferParserType<typeof intParser>
// ^? number | null
const intWithDefault = parseAsInteger.withDefault(0)
type IntDefaultType = inferParserType<typeof intWithDefault>
// ^? number
// Parser map
const parsers = {
page: parseAsInteger.withDefault(1),
enabled: parseAsBoolean
}
type ParsedState = inferParserType<typeof parsers>
// ^? { page: number; enabled: boolean | null }
Nullable
Makes all properties of an object nullable.
type Nullable<T> = {
[K in keyof T]: T[K] | null
} & {}
Usage:
import type { Nullable } from 'nuqs'
type Filters = {
page: number
search: string
}
type NullableFilters = Nullable<Filters>
// ^? { page: number | null; search: string | null }
// Used internally by setState to allow clearing values
setState({ page: null, search: null })
UrlKeys
Helper type to define URL key mappings for renaming search params.
type UrlKeys<Parsers extends Record<string, any>> = Partial<
Record<keyof Parsers, string>
>
Usage:
import { useQueryStates, createSerializer, type UrlKeys } from 'nuqs'
const coordinatesSearchParams = {
latitude: parseAsFloat.withDefault(0),
longitude: parseAsFloat.withDefault(0)
}
// Define URL key mappings
const coordinatesUrlKeys: UrlKeys<typeof coordinatesSearchParams> = {
latitude: 'lat',
longitude: 'lng'
}
// Use in hooks
useQueryStates(coordinatesSearchParams, {
urlKeys: coordinatesUrlKeys
})
// URL: ?lat=51.5&lng=-0.1 instead of ?latitude=51.5&longitude=-0.1
// Use in serializers
createSerializer(coordinatesSearchParams, {
urlKeys: coordinatesUrlKeys
})
Adapter Types
AdapterInterface
Interface that framework adapters must implement.
type AdapterInterface = {
searchParams: URLSearchParams
updateUrl: UpdateUrlFunction
getSearchParamsSnapshot?: () => URLSearchParams
rateLimitFactor?: number
autoResetQueueOnUpdate?: boolean
}
UpdateUrlFunction
Function signature for updating the URL.
type UpdateUrlFunction = (
search: URLSearchParams,
options: Required<AdapterOptions>
) => void
AdapterOptions
Options available to adapters.
type AdapterOptions = Pick<Options, 'history' | 'scroll' | 'shallow'>
UseAdapterHook
Hook signature for creating adapters.
type UseAdapterHook = (watchKeys: string[]) => AdapterInterface
Usage:
import { createAdapter } from 'nuqs/adapters'
import type { UseAdapterHook } from 'nuqs'
const useMyAdapter: UseAdapterHook = (watchKeys) => {
return {
searchParams: new URLSearchParams(window.location.search),
updateUrl: (search, options) => {
// Update URL logic
}
}
}
export const MyAdapter = createAdapter(useMyAdapter)
Loader Types
Accepted input types for loaders.
type LoaderInput =
| URL
| Request
| URLSearchParams
| Record<string, string | string[] | undefined>
| string
LoaderFunction
Function signature for loader functions created with createLoader.
type LoaderFunction<Parsers extends ParserMap> = {
(input: LoaderInput, options?: LoaderFunctionOptions): inferParserType<Parsers>
(input: Promise<LoaderInput>, options?: LoaderFunctionOptions): Promise<inferParserType<Parsers>>
}
LoaderFunctionOptions
Options for loader functions.
type LoaderFunctionOptions = {
/**
* Whether to use strict parsing. If true, the loader will throw an error if
* any of the parsers fail to parse their respective values. If false, the
* loader will return null or their default value for any failed parsers.
*/
strict?: boolean
}
CreateLoaderOptions
Options for creating a loader.
type CreateLoaderOptions<P extends ParserMap> = {
urlKeys?: UrlKeys<P>
}
Usage:
import { createLoader, parseAsInteger, parseAsString } from 'nuqs/server'
import type { LoaderFunction } from 'nuqs/server'
const parsers = {
page: parseAsInteger.withDefault(1),
search: parseAsString
}
const loadSearchParams = createLoader(parsers, {
urlKeys: { page: 'p' }
})
// Use in React Router loader
export async function loader({ request }: LoaderFunctionArgs) {
const { page, search } = loadSearchParams(request)
return { page, search }
}
// Use in Next.js API route
export async function GET(request: Request) {
const { page, search } = loadSearchParams(request.url)
return Response.json({ page, search })
}
Deprecated Types
Parser (deprecated)
Use SingleParser instead. This type is kept for backwards compatibility.
/** @deprecated use SingleParser instead */
type Parser<T> = SingleParser<T>
ParserBuilder (deprecated)
Use SingleParserBuilder instead. This type is kept for backwards compatibility.
/** @deprecated use SingleParserBuilder instead */
type ParserBuilder<T> = SingleParserBuilder<T>
See Also