title | description |
---|---|
Server-Side usage |
Type-safe search params on the server |
If you wish to access the searchParams in a deeply nested Server Component
(ie: not in the Page component), you can use createSearchParamsCache{:ts}
to do so in a type-safe manner.
Built-in validation support is coming. Read the RFC
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)
})
import { searchParamsCache } from './searchParams'
import { type SearchParams } from 'nuqs/server'
type PageProps = {
searchParams: Promise<SearchParams> // Next.js 15+: async searchParams prop
}
export default async function Page({ searchParams }: PageProps) {
// ⚠️ Don't forget to call `parse` here.
// You can access type-safe values from the returned object:
const { q: query } = await 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
function).
Note: the cache only works for server components, but you may share your
parser declaration with useQueryStates
for type-safety in client components:
import {
parseAsFloat,
createSearchParamsCache
} from 'nuqs/server'
export const coordinatesParsers = {
lat: parseAsFloat.withDefault(45.18),
lng: parseAsFloat.withDefault(5.72)
}
export const coordinatesCache = createSearchParamsCache(coordinatesParsers)
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>
</>
)
}
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>
)
}
'use client'
import { useQueryStates } from 'nuqs'
import { coordinatesParsers } from './searchParams'
export function Client() {
const [{ lat, lng }, setCoordinates] = useQueryStates(coordinatesParsers)
// ...
}
Just like useQueryStates
, you can
define a urlKeys
object to map the variable names defined by the parser to
shorter keys in the URL. They will be translated on read and your codebase
can only refer to variable names that make sense for your domain or business logic.
export const coordinatesParsers = {
// Use human-readable variable names throughout your codebase
latitude: parseAsFloat.withDefault(45.18),
longitude: parseAsFloat.withDefault(5.72)
}
export const coordinatesCache = createSearchParamsCache(coordinatesParsers, {
urlKeys: {
// Remap them to read from shorter keys in the URL
latitude: 'lat',
longitude: 'lng'
}
})