目次
Next.jsでブログサイトを作っていて、タグページの2ページ目以降が404エラーになる問題に遭遇しました。原因はgetStaticPaths
でのフィールド取得不備でした。同じ問題で悩んでいる方向けに、解決方法をシンプルに解説します。
発生した問題
ブログサイトで以下のような構造を作っていました:
/tags/javascript ← 1ページ目(正常)
/tags/javascript/2 ← 2ページ目(404エラー)
/tags/react ← 1ページ目(正常)
/tags/react/2 ← 2ページ目(404エラー)
1ページ目は正常に表示されるのに、2ページ目以降で404エラーが発生していました。
原因の調査
デバッグログを追加して確認したところ、getStaticPaths
で全てのタグがPosts: 0
になっていました:
Tag: javascript, Posts: 0, Pages: 0
Tag: react, Posts: 0, Pages: 0
Tag: nextjs, Posts: 0, Pages: 0
明らかに記事は存在するのに、なぜ0件になってしまうのでしょうか?
問題の根本原因
原因はgetStaticPaths
内のgetTagPosts
呼び出しでした:
// 問題のあるコード
export const getStaticPaths: GetStaticPaths = async () => {
const tags = getAllTags()
const paths = []
for (const tag of tags) {
// ここが問題:'slug'しか取得していない
const tagPosts = getTagPosts(tag, ['slug'])
const totalPages = Math.ceil(tagPosts.length / POSTS_PER_PAGE)
// tagPosts.lengthが常に0になる
}
}
getTagPosts
の内部では、記事をtag
フィールドでフィルタリングしていました:
export function getTagPosts(tag: string, fields: string[] = []) {
const posts = slugs
.map((slug) => getPostBySlug(slug, fields))
.filter((post) => post.tag && post.tag.includes(tag)) // ← tagフィールドが必要
}
しかし、getStaticPaths
では['slug']
しかフィールドを指定していないため、tag
フィールドが読み込まれず、フィルタリングが失敗していました。
解決方法
修正は簡単でした。必要なフィールドを明示的に指定するだけです:
// 修正後のコード
export const getStaticPaths: GetStaticPaths = async () => {
const tags = getAllTags()
const paths = []
for (const tag of tags) {
// 修正:tagフィールドも取得する
const tagPosts = getTagPosts(tag, ['slug', 'tag'])
const totalPages = Math.ceil(tagPosts.length / POSTS_PER_PAGE)
for (let page = 2; page <= totalPages; page++) {
paths.push({
params: { tag, page: page.toString() }
})
}
}
return { paths, fallback: false }
}
結果
修正後のビルドでは正常にページが生成されました:
✓ Generating static pages (276/276)
├ ● /tags/[tag]/[page]
├ ├ /tags/javascript/2
├ ├ /tags/javascript/3
├ ├ /tags/react/2
└ └ [+22 more paths]
学んだ教訓
この問題から得られた教訓:
- フィルタリングに使用するフィールドは必須で取得する
- APIの依存関係を明確にする
- デバッグログで実際の値を確認する
特にマークダウンベースのブログやCMSを使用している場合、フロントマターのフィールド(tags、categories、slugなど)をフィルタリングに使用することが多いので、同様の問題が発生しやすいです。
まとめ
getStaticPaths
でデータフィルタリングを行う際は、フィルタリング条件で使用するフィールドも必ず取得するようにしましょう。この小さな見落としが、404エラーの原因になることがあります。
Next.jsでブログサイトを構築している方の参考になれば幸いです。