😿

[Next.js 14 with App router] 動的ルーティング時のメタデータ設定でのしくじり

2024/08/13に公開

やりたいこと

  • Next.js(App Router)での動的ルーティング
    • [slug]をデータ取得時のキーとする
  • データベースから取得した値で動的にメタデータ設定
    • tRPCとPrismaを使用
    • titleやdescriptionなどを設定

Stack

Package Version Description
Next.js 14.2.4 App Router
React 18.3.1 -
TypeScript 5.4.5 -
Node.js 20.13.1 -
tRPC 10.41.0 RPC
Prisma 5.16.1 ORM

App Router(動的ルーティング)でのメタデータ設定

app/post/[postId]/page.tsx

メタデータ設定

generateMetadata

  • postIdでデータベースからデータ(post)を取得
  • 取得した値でメタデータを設定する
    • title

ページコンポーネント

  • postIdでデータベースからデータ(post)を取得
  • 取得した値でページレンダリング

メタデータ設定とページレンダリングのためにデータ取得を繰り返しても問題ない

どこかの記事で、「generateMetadata とページコンポーネントでそれぞれデータを取得しても、Next.js が自動的にキャッシュしてくれるから大丈夫。」というのを見た。

Prismaのクエリログを確認

データベースへの問い合わせクエリが複数回、発行されている

  • generateMetadata内でのクエリ発行
  • ページコンポーネント内でのクエリ発行
  • キャッシュされてない

generateMetadata内のデータ取得をやめると、発行されるクエリは減る

  • ページコンポーネント内で問い合わせているクエリのみとなる

ドキュメントを確認

https://nextjs.org/docs/app/api-reference/functions/generate-metadata

fetch requests are automatically memoized for the same data across generateMetadata, generateStaticParams, Layouts, Pages, and Server Components.
React cache can be used if fetch is unavailable.

キャッシュされるのはfetchのとき。
fetchでない場合は、cacheしないといけない。

参考

https://zenn.dev/yu_ta_9/articles/e28da9cb6febdb

cacheするようにしたら改善しました

きちんと、ドキュメントも確認しないといけませんね。
中途半端な理解と思い込みは怖い。反省。

Discussion