2021-12-24
Next.js×microCMSでタグ一覧ページを作成。[ネストされた動的なルーティング][getStaticPaths]
PV

フィールド作成
作成の仕方自体は、
カテゴリの作成方法
で、microCMSのコンテンツAPIにタグとかカテゴリとかを作成しておきます。
こんな感じです。
ブログ側のAPIスキーマに先ほど作成したカテゴリなりタグなりを参照フィールドとして指定したものを追加します。
こんな感じです。
ディレクトリ構成
ディレクトリ構成はこんな感じで作りました。
└── tags
│       ├── [tag]
│       │   └── page
│       │       └── [id].js
│       ├── [tag].js
│       └── index.js/tags
がtag一覧ページです。本サイトヘッダーからTAGに行ってみてください。/tags/[tag]
が特定タグがついている記事の一覧ページです。/tags/[tag]/page/[id]
が特定タグがついている記事のページネーションのための実装です。
ページネーション実装はこちらの記事も参考にしてください。
実装のポイント
getStaticPathsでページネーション用のパスを作成する際に、ネストされた動的なルーティングを実装する部分で少し詰まりました。
出てきたエラー文:
Error: Extra keys returned from getStaticPaths in /tags/[tag]/page/[id] (resPaths) Expected: { paths: [], fallback: boolean } See here for more info: https://nextjs.org/docs/messages/invalid-getstaticpaths-value
結論、
export const getStaticPaths = async () => {
  const tags = await client.get({ endpoint: "tags", queries: { limit: 100 } });
  const resPaths = await Promise.all(
    tags.contents.map((tag) => {
      const result = client
        .get({
          endpoint: "blogs",
          queries: {
            filters: `tags[contains]${tag.id}`,
            limit: 100,
          },
        })
        .then(({ totalCount }) => {
          const range = (start, end) =>
            [...Array(end - start + 1)].map((_, i) => start + i);
          return range(1, Math.ceil(totalCount / 4)).map(
            (i) => `/tags/${tag.id}/page/${i}`
          );
        });
      return result;
    })
  );
  const paths = resPaths.flat();
  return { paths, fallback: false };
};
みたいな感じでやりました。
get /tags でtag全部をとり、tagをmapで回して一つの特定のtagに対してその特定のtagがついている記事をgetします。
ポイントは作成した配列をflat化している点です。
何もしない場合:
[
  [ { params: [Object] } ],
  [ { params: [Object] } ],
  [ { params: [Object] } ],
  [ { params: [Object] } ],
  [ { params: [Object] }, { params: [Object] } ],
  [ { params: [Object] }, { params: [Object] } ],
  [ { params: [Object] }, { params: [Object] } ]
]
となるので、以下の形にしなければいけないので、flat()で配列をflat化する。
[
  { params: { tag: 'a__qj7f004qi', id: 1 } },
  { params: { tag: '2e7y_miiq', id: 1 } },
  { params: { tag: 'pv74k4x3u5', id: 1 } },
  { params: { tag: 'nsppv8907xeo', id: 1 } },
  { params: { tag: 'pkcqsc-2qdz', id: 1 } },
  { params: { tag: 'pkcqsc-2qdz', id: 2 } },
  { params: { tag: 'e_ylg36dhaj', id: 1 } },
  { params: { tag: 'e_ylg36dhaj', id: 2 } },
  { params: { tag: 'n54oitv4eq', id: 1 } },
  { params: { tag: 'n54oitv4eq', id: 2 } }
]参考リンク
Next.js: getStaticPaths for nested dynamic routes
Next.js + microCMSでカテゴリ一覧ページを作る
microCMS + Next.jsでJamstackブログを作ってみよう