Skip to main content

Overview

The createLoader function creates a type-safe loader for parsing search parameters from various input types. It’s designed for one-off parsing operations in loaders, API routes, server components, and other server-side contexts.

Function Signature

function createLoader<Parsers extends ParserMap>(
  parsers: Parsers,
  options?: CreateLoaderOptions<Parsers>
): LoaderFunction<Parsers>

Parameters

parsers
ParserMap
required
An object mapping search param keys to their parser configurations. Each parser defines how to parse and serialize values.
const parsers = {
  q: parseAsString,
  page: parseAsInteger.withDefault(1),
  tags: parseAsArrayOf(parseAsString)
}
options
CreateLoaderOptions<Parsers>
Optional configuration object.

Return Value

Returns a LoaderFunction with the following signature:
type LoaderFunction<Parsers extends ParserMap> = {
  // Synchronous overload
  (
    input: LoaderInput,
    options?: LoaderFunctionOptions
  ): inferParserType<Parsers>
  
  // Asynchronous overload (for Next.js 15+ Promise searchParams)
  (
    input: Promise<LoaderInput>,
    options?: LoaderFunctionOptions
  ): Promise<inferParserType<Parsers>>
}

LoaderInput

The loader accepts multiple input types:
type LoaderInput =
  | URL
  | Request
  | URLSearchParams
  | Record<string, string | string[] | undefined>
  | string

LoaderFunctionOptions

strict
boolean
default:false
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.
type LoaderFunctionOptions = {
  strict?: boolean
}

Type Definitions

ParserMap

type ParserMap = Record<string, ParserWithOptionalDefault<any>>

type ParserWithOptionalDefault<T> = GenericParserBuilder<T> & {
  defaultValue?: T
}

inferParserType

TypeScript automatically infers the return type based on your parsers:
const loadSearchParams = createLoader({
  count: parseAsInteger,                      // number | null
  active: parseAsBoolean.withDefault(false),  // boolean
  tags: parseAsArrayOf(parseAsString)         // string[] | null
})

const params = loadSearchParams(request)
// TypeScript infers:
// params: {
//   count: number | null,
//   active: boolean,
//   tags: string[] | null
// }

Examples

Basic Usage

import { createLoader, parseAsString, parseAsInteger } from 'nuqs/server'

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

const { q, page } = loadSearchParams('?q=hello&page=2')
// q: string | null
// page: number

With URL Object

const url = new URL('https://example.com/search?q=hello&page=2')
const { q, page } = loadSearchParams(url)

With Request Object

export async function GET(request: Request) {
  const params = loadSearchParams(request)
  // ...
}

With Next.js 15 Async searchParams

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

export default async function Page({ searchParams }) {
  const { q, page } = await loadSearchParams(searchParams)
  // ...
}

Strict Mode

const loadSearchParams = createLoader({
  page: parseAsInteger
})

try {
  // This will throw because "abc" is not a valid integer
  const { page } = loadSearchParams('?page=abc', { strict: true })
} catch (error) {
  console.error(error)
  // Error: [nuqs] Error while parsing query `abc` for key `page`
}

// Without strict mode, invalid values return null or default
const { page } = loadSearchParams('?page=abc')  // page: null

URL Keys Mapping

const loadSearchParams = createLoader(
  {
    searchQuery: parseAsString,
    pageNumber: parseAsInteger.withDefault(1)
  },
  {
    urlKeys: {
      searchQuery: 'q',
      pageNumber: 'page'
    }
  }
)

// URL: ?q=laptop&page=2
const { searchQuery, pageNumber } = loadSearchParams('?q=laptop&page=2')
// searchQuery: "laptop"
// pageNumber: 2

Loaders Guide

Learn how to use loaders in different frameworks

createSearchParamsCache

Cache search params in server components

Parsers

Learn about available parser types

Build docs developers (and LLMs) love