Irohabook
0
89

Next.js の generateMetadata の注意点:fetch は開発環境で重複リクエストするが、本番環境ではデータがキャッシュされる

メタデータを動的に変える場合、App Router では generateMetadata を使います。多くのウェブサイトでは

import Head from 'next/head'

というコードが紹介されていますが、Head は App Router で使われない。

generateMetadata は Metadata をつくる重要な関数で、コンポーネント内部に書きます。わかりやすく言うと、最終的なテンプレートをつくる関数(以降「テンプレート関数」といいます)と同じファイルに書きます。

ちなみにこの関数名は変更不可で、変更するとメタタグはデフォルトに書き換えられます。

API を使う場合、generateMetadata もテンプレート関数も fetch でデータを取得し、そのデータからタイトルなどのメタ情報やページ本文をつくります。

ここまでのまとめ:
テンプレート関数と generateMetadata はどちらも同じ URL にリクエストし、取得したデータを使ってメタやらなんやらをつくる

もう一度言います。generateMetadata とテンプレート関数は同じ URL に対してリクエストします。一見狂っています。二つのうまい棒を一つずつレジで購入するくらい意味不明です。この二重リクエスト問題は不思議なことにインターネットでほとんど話題になっていません。

GitHub や Stack Overflow でこの問題を相談しているユーザーが少ないのは、私がなにか壮大な勘違いをしているせいでしょうか? あるいは、この問題をとりあげる人が少ないのは、fetch がキャッシュ機能を備えているから?

fetch はキャッシュ機能があり、なんと二重リクエストは自動で阻止されます。一回リクエストしたデータはどこかにキャッシュされ、再び同じ URL にリクエストしたさいはそのキャッシュデータを参照します。

しかし私の環境では API サーバーはあいかわらず二重リクエストを受けました。結論から言うと、その原因は Next.js プロジェクトをビルドしていなかったせい。ビルドしたらリクエストは一回になりました。

結論
同一 URL への fetch は、何回やっても実際のリクエストは一回のみ。ただしそのキャッシュ機能は開発環境では無効。有効にしたいならビルドする。

こうして generateMetadata の重複 fetch をどうするか問題は解決されました。

次の記事

JavaScriptの基本