mcpField
N
nextjs-pathname-id-fetch

nextjs-pathname-id-fetch

github.com/wsimmonds開発109295 回インストール53 週間前に更新
リポジトリ

nextjs-pathname-id-fetch について

Next.js 開発者向けに、動的ルートのパラメーターからページデータを取得する方法に絞ったスキルです。Server Component を保ち、Next.js 15+ では `params` を await する手順を示します。

主な機能

  1. 01角括弧付き動的ルートの作成
  2. 02params から識別子を取得
  3. 03パスパラメーターによるデータ取得
  4. 04ページを Server Component として維持
  5. 05パラメーターの明示的な型定義

活用シーン

  1. 01製品 ID に基づく詳細ページ表示
  2. 02slug に基づく記事コンテンツの取得
  3. 03管理パスの注文 ID によるデータ参照

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wsimmonds/claude-nextjs-skills --skill nextjs-pathname-id-fetch

インストール後、Claude Code で/nextjs-pathname-id-fetchを入力して読み込まれたか確認します。

詳細

Next.js:パス名の ID に基づくデータ取得パターン

このパターンを使用する場面

URL に含まれる識別子に基づいてページのデータを読み込む必要がある場合は、このパターンを使用します。よくあるケースは次のとおりです。

  • 商品、投稿、ユーザーの詳細ページ(/products/{id}、/blog/{slug})
  • 選択したリソースを掘り下げる管理ダッシュボード(/admin/orders/{orderId})
  • ネストしたパスを持つドキュメントやナレッジベース(/docs/getting-started/installation)

現在の URL パスに応じてデータを変更する要件がある場合、ルートセグメントは動的にする必要があります(例:[id]、[slug]、[...slug])。

パターン

✅ 推奨される実装

1. Create a dynamic folder: app/[id]/page.tsx
2. Access the parameter: const { id } = await params;
3. Fetch data using that identifier
4. Render the requested information

❌ 落とし穴

Using app/page.tsx for this scenario prevents access to per-path identifiers.

実装例の全体

// app/[id]/page.tsx

// IMPORTANT: Server component (NO 'use client' needed!)
export default async function ProductPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  // Next.js 15+: params must be awaited
  const { id } = await params;

  // Fetch data using the ID from the URL
  const response = await fetch(`https://api.example.com/products/${id}`);
  const product = await response.json();

  // Return JSX with the fetched data
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <p>Price: ${product.price}</p>
    </div>
  );
}

ファイル構成

app/
└── [id]/                 ← Dynamic route folder with brackets
    └── page.tsx          ← Server component page

URL マッピング:

  • /123 → params = { id: '123' }
  • /abc → params = { id: 'abc' }
  • /product-xyz → params = { id: 'product-xyz' }

主なルール

1. フォルダー名には必ず角括弧を使用する
✅ app/[id]/page.tsx
✅ app/[productId]/page.tsx
✅ app/[slug]/page.tsx
❌ app/id/page.tsx        (no brackets = static route)
❌ app/page.tsx            (can't access params here)
2. これはサーバーコンポーネントです(デフォルト)
// ✅ CORRECT - No 'use client' needed
export default async function Page({ params }) {
  const { id } = await params;
  const data = await fetch(`/api/${id}`);
  return <div>{data.name}</div>;
}

// ❌ WRONG - Don't add 'use client' for server components
'use client';  // ← Remove this!
export default async function Page({ params }) { ... }
3. Params は await する必要があります(Next.js 15+)
// ✅ CORRECT - Next.js 15+
export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;  // Must await
  // ...
}

// ⚠️ OLD (Next.js 14 and earlier - deprecated)
export default async function Page({
  params,
}: {
  params: { id: string };
}) {
  const { id } = params;  // No await needed in old versions
  // ...
}
4. シンプルに保つ — ネストしすぎない
✅ app/[id]/page.tsx              (simple, clean)
❌ app/products/[id]/page.tsx     (only if explicitly required!)

要件で /products/[id] が明示的に求められていない限り、構成はトップレベル(app/[id]/page.tsx)に保ちます。

TypeScript:any 型は絶対に使用しない

このコードベースでは @typescript-eslint/no-explicit-any が有効になっています。any を使用するとビルドに失敗します。

// ❌ WRONG
function processProduct(product: any) { ... }

// ✅ CORRECT - Define proper types
interface Product {
  id: string;
  name: string;
  price: number;
}

function processProduct(product: Product) { ... }

// ✅ ALSO CORRECT - Use unknown if type truly unknown
function processData(data: unknown) {
  // Type guard required before using
  if (typeof data === 'object' && data !== null) {
    // ...
  }
}

よくあるバリエーション

異なるパラメーター名
// app/[productId]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ productId: string }>;
}) {
  const { productId } = await params;
  // ...
}

// app/[slug]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  // ...
}
複数のパラメーター
// app/[category]/[id]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ category: string; id: string }>;
}) {
  const { category, id } = await params;
  const data = await fetch(`/api/${category}/${id}`);
  // ...
}

動作する実装例の全体

// app/[id]/page.tsx - Product detail page

interface Product {
  id: string;
  name: string;
  description: string;
  price: number;
  inStock: boolean;
}

export default async function ProductPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  // Get the ID from the URL
  const { id } = await params;

  // Fetch product data using the ID
  const response = await fetch(
    `https://api.example.com/products/${id}`,
    { cache: 'no-store' } // Always fresh data
  );

  if (!response.ok) {
    throw new Error('Failed to fetch product');
  }

  const product: Product = await response.json();

  // Render the product
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>

      <div>
        <strong>Price:</strong> ${product.price}
      </div>

      <div>
        <strong>Availability:</strong>{' '}
        {product.inStock ? 'In Stock' : 'Out of Stock'}
      </div>
    </div>
  );
}

簡単なチェックリスト

パス名に基づく詳細ページをリリースする前に、次の項目を確認してください。

  • ルートフォルダー名に角括弧を使用している(例:app/[id]/page.tsx)
  • コンポーネントがサーバー側にとどまっている('use client' は不要)
  • Next.js 15+ では params プロパティの型を Promise<{ id: string }> にしている
  • params を await し、識別子を安全に読み取っている
  • データ取得ロジックでその識別子を使用している
  • レンダリングで読み込み中やエラーの状態を適切に処理している
  • 型を明示している — any に頼らない

代わりに包括的なスキルを使用する場面

このマイクロスキルでは、シンプルな「パス名の ID に基づくデータ取得」パターンを扱います。次の場合は、包括的な nextjs-dynamic-routes-params スキルを使用してください。

  • キャッチオールルート([...slug])
  • オプショナルキャッチオールルート([[...slug]])
  • 複雑な複数パラメーターのルーティング
  • 高度なルーティングアーキテクチャ
  • 詳細なルーティングの判断

「URL の ID でデータを取得する」というシンプルなケースであれば、このスキルだけで十分です。

コメント