Next.js×microCMSでタグ機能を作成する![ネストされた動的なルーティング][getStaticPaths]

Pocket

こんにちは!やむちゃです!

今回は、Next.jsとmicroCMSで作成されたブログにタグ一覧ページを作成した際にエラーが出て詰まったのでメモ程度に共有していきます。

ブログ全体のソースコードはこちらになります。

目次

microCMSでフィールドを作成

作成の仕方自体は、
カテゴリの作成方法
と同様で、microCMSのコンテンツAPIにタグフィールドを作成しておきます。

上記で作成したタグAPIを参照フィールドとしてブログ側のAPIスキーマに追加します。

Next.jsでのディレクトリ構成

ディレクトリ構成は、pages配下が

└── tags
│       ├── [tag]
│       │   └── page
│       │       └── [id].js
│       ├── [tag].js
│       └── index.js

このようになっています。

/tags
が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ブログを作ってみよう

Pocket

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次