nuqs-scaffolder について
パラメータ仕様から nuqs の関連ファイル一式を生成するテンプレート駆動のスキルです。Next.js ページに URL ベースの状態を導入する開発者向けで、クライアントとサーバーのパーサー定義を共有します。
主な機能
- 01仕様から nuqs ファイルを生成
- 02複数のクエリパラメーター型に対応
- 03クライアントとサーバーのパーサーマップを作成
- 04フィルターコンポーネントと任意のテストを生成
- 05出力パスと命名規則を設定
活用シーン
- 01URL ベースの検索、絞り込み、ページネーション、並べ替えの追加
- 02場当たり的な useState の絞り込みを nuqs に置換
- 03クライアントとサーバーのパーサー定義の統一
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill nuqs-scaffolderインストール後、Claude Code で/nuqs-scaffolderを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdconfig.jsongotchas.mdmetadata.jsonassets/templates/filters.test.tsx.templatefilters.tsx.templatesearchParams.server.ts.templatesearchParams.ts.templatespec.json.templatereferences/conventions.md詳細
nuqs スキャフォルダー
1 つの仕様から、整合性のある nuqs ファイル一式を生成します。このスキルは テンプレート駆動型 です。仕様を読み、テンプレートをコピーして、プレースホルダーを置き換えます。ビルド手順もコード生成ランタイムもありません。テンプレートそのものが成果物です。
適用するタイミング
次のような場合に、このスキルを使用します。
- 新しい Next.js ページで、URL に紐づくフィルター、ページネーション、検索、並べ替えの状態が必要な場合
- 既存ページの場当たり的な
useStateフィルターを nuqs に統一する場合 - コードレビューでパーサー定義のクライアント/サーバー間の不整合が繰り返し指摘されている場合。このスキルでは両方が同じマップをインポートするため、機械的に不整合を防止できます
- ユーザーから「これらのクエリパラメーターに tRPC 用の Standard Schema 検証を追加して」と依頼された場合。生成される
searchParams.server.tsには、すでにスキーマがエクスポートされています
コードベースにレガシーな nuqs パターンがある場合は、先に nuqs-codemod-runner スキルを実行してください。
使用方法
- 仕様を読み込むか、作成します。
assets/templates/spec.template.jsonを基にして、name、module、paramsを入力します。詳しくは、以下の「仕様の形式」を参照してください。 - 仕様から導き出した値でプレースホルダーを置き換え、各テンプレートをレンダリングします。
config.jsonから決定したパスに、レンダリングした各ファイルを書き込みます(呼び出しごとに上書きできます)。- コミット前に差分をユーザーに提示します。 このスキルが既存ファイルを変更することはありません。対象パスにファイルが存在する場合は、上書きする前に確認してください。
レンダリングはエージェントが行います。Claude がテンプレートエンジンです。各テンプレートには、プレースホルダーのスロット名と置換ルールを示すマーカー(/*= ... =*/)が付いています。
仕様の形式
{
"name": "Search", // PascalCase — drives the exported symbol names
"module": "search", // kebab-case — drives file paths and the "module" folder
"params": {
"q": { "type": "string", "default": "" },
"page": { "type": "integer", "default": 1 },
"limit": { "type": "integer", "default": 10 },
"categories": { "type": "array-of-string-native", "default": [] },
"sort": { "type": "string-literal", "values": ["asc","desc"], "default": "asc" },
"minPrice": { "type": "float", "default": null },
"lastSeen": { "type": "iso-date", "default": null }
}
}
サポートされる type の値
type | 使用するパーサー | 備考 |
|---|---|---|
string | parseAsString | |
integer | parseAsInteger | |
float | parseAsFloat | |
boolean | parseAsBoolean | |
iso-date | parseAsIsoDate | 日付のみ |
iso-date-time | parseAsIsoDateTime | 日付と時刻 |
timestamp | parseAsTimestamp | エポックからのミリ秒 |
hex | parseAsHex | 数値。URL 形式は 16 進数 |
index | parseAsIndex | コードでは 0 始まり、URL では 1 始まり |
array-of-string | parseAsArrayOf(parseAsString) | ?tags=a,b,c |
array-of-string-native | parseAsNativeArrayOf(parseAsString) | ?tag=a&tag=b — nuqs ≥ 2.7 が必要 |
string-literal | parseAsStringLiteral(values) | values: string[] が必要 |
number-literal | parseAsNumberLiteral(values) | values: number[] が必要 |
json | parseAsJson(SchemaName.parse) | Zod スキーマのスタブを生成します。default は個別に指定してください |
default が null の場合、パラメーターは null 許容になります。それ以外の場合、テンプレートでは .withDefault(...) を使用します。
利用可能なテンプレート
| テンプレート | 出力先(デフォルト) | 読み込み条件 |
|---|---|---|
searchParams.ts.template | lib/{module}-search-params.ts | 常に |
searchParams.server.ts.template | lib/{module}-search-params.server.ts | 常に |
filters.tsx.template | components/{module}/{name}-filters.tsx | 常に |
filters.test.tsx.template | components/{module}/{name}-filters.test.tsx | config.generate_tests が true の場合 |
spec.json.template | 任意の場所 — ユーザー向けのひな形 | 初回実行時のプロンプト |
エディターがプレースホルダーマーカーに構文強調表示を適用しないよう、テンプレートファイルの末尾には .template が付いています。元の拡張子は .template の直前に保持されるため、レンダリング後のファイル形式をひと目で確認できます。
パスは config.json で設定できます。glob、ファイル名のスタイル(kebab または PascalCase)、テストを出力するかどうかを上書きできます。
プレースホルダーのリファレンス
すべてのテンプレートで同じプレースホルダー構文を使用します。エージェントはこれらを一度に置換します。
| プレースホルダー | ソース | 例 |
|---|---|---|
__NAME__ | spec.name | Search |
__name__ | spec.name の camelCase 形式 | search |
__module__ | spec.module | search |
/*= PARSERS =*/ | spec.params を反復処理 → key: parseAsXxx.withDefault(...) の行 | テンプレートを参照 |
/*= COMPONENT_FIELDS =*/ | spec.params を反復処理 → 型ごとに入力または選択欄を1つ | テンプレートを参照 |
/*= TEST_CASES =*/ | spec.params を反復処理 → デフォルト値ごとにアサーションを1つ | テンプレートを参照 |
/*= NULLABLE_IMPORTS =*/ | いずれかのパラメーターが nullable の場合、Nullable ヘルパーのインポートを追加 | 条件付き |
/*= ZOD_SCHEMAS =*/ | json 型のパラメーターに対して、Zod スキーマのスタブを出力 | 条件付き |
/*= ... =*/ マーカーはエージェントへの指示であり、文字どおりに置換するものではありません。マーカー全体(/*= =*/ の区切り文字を含む)を展開した内容に置き換えてください。
規約
references/conventions.md を読み、以下を確認してください。
- ファイル名(kebab-case)とその理由
- インポートの順序(外部 → nuqs → 内部 → 相対)とその理由
- サーバーファイルが
app/内ではなく、同じ階層に存在する理由 - テンプレートをフォークするタイミング(通常は不要です)
セットアップ
config.json には、Next.js App Router の妥当なデフォルト設定があらかじめ入力されています。リポジトリで異なる規約を使用している場合に限り、上書きしてください。
{
"lib_dir": "lib",
"components_dir": "components",
"generate_tests": true,
"test_runner": "vitest"
}
初回使用時に仕様ファイルが提供されていない場合、エージェントは AskUserQuestion を使ってユーザーに仕様を確認してください。
関連スキル
nuqs— これらのテンプレートに反映されているベストプラクティスのリファレンスです。テンプレートがこのような構成になっている理由を理解するために読んでください。nuqs-codemod-runner— 既存のページを nuqs v2.5 より前のバージョンから移行する場合は、このスキルより先に実行してください。
注意点
使用中に判明したエッジケースについては、gotchas.md を参照してください。