【nuqs】server, clientで共通の設定を作る
こんにちは、フリーランスエンジニアの太田雅昭です。
nuqs
nuqsは、URLのクエリパラメータを簡単に扱えるようにするライブラリです。2025年9月13日現在多くのスポンサーとコントリビューターが参加しています。
検証バージョン
- nuqs: ^2.6.0
server, clientは区別されている
parserはserverとclientとで区別されています。例えばparseAsStringLiteralを作ります。
import { parseAsStringLiteral } from "nuqs";
export const parser = parseAsStringLiteral(CLIP_TYPES).withDefault('video')
これをserver側で使おうとすると、下記のエラーとなります。
Attempted to call parseAsStringLiteral() from the server but parseAsStringLiteral is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.
そのためserverで使うパーサーは、nuqsからではなく、nuqs/serverからimportする必要があります。
しかしこれでは、共通化ができません。
関数を受け取れるようにする
parseAsStringなどのパーサーは、型がserver, clientとで同じです。それを利用して、関数を受け取れるようにします。
// 型のみ使用しているため、server, clientどちらでも使用可能
export type CreateParsersParams = Pick<typeof import('nuqs'),
'parseAsString' |
'parseAsStringLiteral'
>
// パラメータを作成
export function createParsers(p: CreateParsersParams) {
return {
type: p.parseAsStringLiteral(['video', 'image']).withDefault('video'),
query: p.parseAsString.withDefault(''),
}
}
これをサーバー、クライアントそれぞれで使用します。
"use server
import * as nuqs from 'nuqs/server';
import { createLoader } from 'nuqs/server';
const parsers = createParsers(nuqs)
const loadSearchParams = createLoader(parsers)
type Props = {
searchParams: Promise<any>
}
export default async function ServerComponent(props: Props) {
const searchParams = await loadSearchParams(props.searchParams)
...
}
"use client"
import * as nuqs from 'nuqs';
import { useQueryState } from 'nuqs';
const parsers = createParsers(nuqs)
function Component() {
const [type, setType] = useQueryState('type', parsers.type);
const [query, setQuery] = useQueryState('query', parsers.query);
...
}