2021-12-24

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

PV
blogimg

フィールド作成


作成の仕方自体は、
カテゴリの作成方法
で、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ブログを作ってみよう

アフィリエイトリンク