Documentation Index Fetch the complete documentation index at: https://mintlify.com/47ng/nuqs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The createSerializer function creates a type-safe serializer for generating URLs with search parameters. It’s useful for creating links, redirects, and programmatic navigation with properly formatted query strings.
Function Signature
function createSerializer <
Parsers extends ParserMap ,
BaseType extends Base = Base ,
Return = string
>(
parsers : Parsers ,
options ?: CreateSerializerOptions < Parsers >
) : SerializeFunction < Parsers , BaseType , Return >
Parameters
An object mapping search param keys to their parser configurations. const parsers = {
q: parseAsString ,
page: parseAsInteger ,
category: parseAsString
}
options
CreateSerializerOptions<Parsers>
Optional configuration object. When true, values matching their parser’s default value will be omitted from the URL to keep URLs clean. const serialize = createSerializer (
{ page: parseAsInteger . withDefault ( 1 ) },
{ clearOnDefault: true }
)
serialize ({ page: 1 }) // "" (omitted because it's the default)
serialize ({ page: 2 }) // "?page=2"
Map internal state keys to different URL query parameter names. type UrlKeys < Parsers > = Partial < Record < keyof Parsers , string >>
Example: const serialize = createSerializer (
{ query: parseAsString },
{ urlKeys: { query: 'q' } }
)
serialize ({ query: 'laptop' }) // "?q=laptop"
processUrlSearchParams
(searchParams: URLSearchParams) => URLSearchParams
A function to post-process the URLSearchParams before serialization. Useful for adding custom logic or additional parameters. const serialize = createSerializer (
{ q: parseAsString },
{
processUrlSearchParams : ( params ) => {
params . set ( 'utm_source' , 'app' )
params . sort ()
return params
}
}
)
Return Value
Returns a SerializeFunction with two overloads:
type SerializeFunction <
Parsers extends ParserMap ,
BaseType extends Base = Base ,
Return = string
> = {
// Generate query string from values
( values : Partial < Nullable < inferParserType < Parsers >>>) : Return
// Append/amend query string to base URL
(
base : BaseType ,
values : Partial < Nullable < inferParserType < Parsers >>> | null
) : Return
}
Base Types
type Base = string | URLSearchParams | URL
Nullable Type Helper
type Nullable < T > = {
[ K in keyof T ] : T [ K ] | null
}
Values can be set to null to remove them from the URL.
Type Definitions
ParserMap
type ParserMap = Record < string , ParserWithOptionalDefault < any >>
type ParserWithOptionalDefault < T > = GenericParserBuilder < T > & {
defaultValue ?: T
}
CreateSerializerOptions
type CreateSerializerOptions < Parsers extends ParserMap > = Pick <
Options ,
'clearOnDefault'
> & {
urlKeys ?: UrlKeys < Parsers >
processUrlSearchParams ?: ( searchParams : URLSearchParams ) => URLSearchParams
}
inferParserType
TypeScript automatically infers types based on your parsers:
const serialize = createSerializer ({
count: parseAsInteger ,
active: parseAsBoolean ,
tags: parseAsArrayOf ( parseAsString )
})
// TypeScript knows the shape of the values object
serialize ({
count: 42 , // number | null
active: true , // boolean | null
tags: [ 'a' , 'b' ] // string[] | null
})
Examples
Generate Query String
import { createSerializer , parseAsString , parseAsInteger } from 'nuqs/server'
const serialize = createSerializer ({
q: parseAsString ,
page: parseAsInteger ,
category: parseAsString
})
serialize ({ q: 'laptop' , page: 2 })
// "?q=laptop&page=2"
serialize ({ category: 'electronics' })
// "?category=electronics"
Append to Base URL
const serialize = createSerializer ({
q: parseAsString ,
page: parseAsInteger
})
// Append to a path
serialize ( '/search' , { q: 'laptop' , page: 2 })
// "/search?q=laptop&page=2"
// Amend existing query string
serialize ( '/search?sort=price' , { q: 'laptop' })
// "/search?sort=price&q=laptop"
// Use with URL object
const url = new URL ( 'https://example.com/search' )
serialize ( url , { q: 'laptop' })
// "https://example.com/search?q=laptop"
// Use with URLSearchParams
const params = new URLSearchParams ( '?sort=price' )
serialize ( params , { q: 'laptop' })
// "?sort=price&q=laptop"
Remove Parameters with null
const serialize = createSerializer ({
q: parseAsString ,
page: parseAsInteger ,
category: parseAsString
})
// Remove specific parameters
serialize ( '/search?q=laptop&page=2&category=electronics' , {
category: null // Remove category
})
// "/search?q=laptop&page=2"
// Remove all parameters by passing null as second argument
serialize ( '/search?q=laptop&page=2' , null )
// "/search"
Default Value Behavior
const serialize = createSerializer ({
page: parseAsInteger . withDefault ( 1 ),
limit: parseAsInteger . withDefault ( 20 )
})
serialize ({ page: 1 , limit: 20 })
// "" (both values are defaults, so omitted)
serialize ({ page: 2 , limit: 20 })
// "?page=2" (limit omitted because it's the default)
serialize ({ page: 1 , limit: 50 })
// "?limit=50" (page omitted because it's the default)
Disable clearOnDefault
const serialize = createSerializer (
{
page: parseAsInteger . withDefault ( 1 )
},
{ clearOnDefault: false }
)
serialize ({ page: 1 })
// "?page=1" (included even though it's the default)
URL Keys Mapping
const serialize = createSerializer (
{
searchQuery: parseAsString ,
pageNumber: parseAsInteger ,
itemsPerPage: parseAsInteger
},
{
urlKeys: {
searchQuery: 'q' ,
pageNumber: 'page' ,
itemsPerPage: 'limit'
}
}
)
serialize ({
searchQuery: 'laptop' ,
pageNumber: 2 ,
itemsPerPage: 50
})
// "?q=laptop&page=2&limit=50"
Post-Processing
const serialize = createSerializer (
{
q: parseAsString ,
page: parseAsInteger
},
{
processUrlSearchParams : ( params ) => {
// Add analytics parameters
params . set ( 'utm_source' , 'app' )
params . set ( 'utm_medium' , 'link' )
// Sort parameters alphabetically
params . sort ()
return params
}
}
)
serialize ({ q: 'laptop' , page: 2 })
// "?page=2&q=laptop&utm_medium=link&utm_source=app"
With Link Components (Next.js)
import Link from 'next/link'
import { createSerializer , parseAsString , parseAsInteger } from 'nuqs/server'
const serialize = createSerializer ({
q: parseAsString ,
page: parseAsInteger ,
category: parseAsString
})
export function ProductLink ({ category } : { category : string }) {
return (
< Link href = { serialize ( '/products' , { category , page: 1 }) } >
View { category }
</ Link >
)
}
export function PaginationLink ({ page } : { page : number }) {
return (
< Link href = { serialize ({ page }) } >
Page { page }
</ Link >
)
}
Server-Side Redirects (Next.js)
import { redirect } from 'next/navigation'
import { createSerializer , parseAsString } from 'nuqs/server'
const serialize = createSerializer ({
q: parseAsString
})
export async function searchAction ( formData : FormData ) {
'use server'
const query = formData . get ( 'q' ) as string
// Redirect to search results
redirect ( serialize ( '/search' , { q: query }))
}
API Routes
import { createSerializer , parseAsInteger } from 'nuqs/server'
const serialize = createSerializer ({
page: parseAsInteger ,
limit: parseAsInteger
})
export async function GET ( request : Request ) {
const nextPageUrl = serialize (
new URL ( request . url ),
{ page: 2 , limit: 20 }
)
return Response . json ({
data: [ ... ],
nextPage: nextPageUrl
})
}
Complex Serialization
import {
createSerializer ,
parseAsString ,
parseAsInteger ,
parseAsArrayOf ,
parseAsIsoDateTime ,
parseAsStringLiteral
} from 'nuqs/server'
const serialize = createSerializer (
{
search: parseAsString ,
page: parseAsInteger . withDefault ( 1 ),
limit: parseAsInteger . withDefault ( 20 ),
tags: parseAsArrayOf ( parseAsString ),
from: parseAsIsoDateTime ,
to: parseAsIsoDateTime ,
sortBy: parseAsStringLiteral ([ 'asc' , 'desc' ] as const )
},
{
urlKeys: {
search: 'q' ,
limit: 'per_page'
}
}
)
serialize ({
search: 'laptop' ,
page: 2 ,
tags: [ 'electronics' , 'sale' ],
from: new Date ( '2024-01-01' ),
sortBy: 'desc'
})
// "?q=laptop&page=2&tags=electronics,sale&from=2024-01-01T00:00:00.000Z&sortBy=desc"
Type Safety
The serializer is fully type-safe:
const serialize = createSerializer ({
count: parseAsInteger ,
active: parseAsBoolean ,
tags: parseAsArrayOf ( parseAsString )
})
// ✅ Valid
serialize ({
count: 42 ,
active: true ,
tags: [ 'a' , 'b' ]
})
// ❌ TypeScript error: wrong type
serialize ({ count: 'not a number' })
// ❌ TypeScript error: unknown key
serialize ({ unknown: 'value' })
// ✅ Valid: null removes parameter
serialize ({ count: null })
Serializer Guide Learn how to use serializers for URLs
createLoader Parse search params with createLoader
createSearchParamsCache Cache search params in server components
Parsers Learn about available parser types