動的メタデータ
商品ページのタイトルが全部同じ
前回、ルートレイアウトに metadata を書いてタイトルを付けました。ところが商品詳細ページを開いても、タブの文字は fleama のままです。スニーカーの画面も革靴の画面も同じタイトルなので、タブを何枚も開くと見分けが付きません。検索結果でも同じ見出しが並ぶことになります。
商品ごとに違うタイトルを出したいのですが、export const metadata は固定の値しか書けません。商品名は URL の id を見ないと分からないので、この形では間に合いません。
値ではなく関数で返す
そこで使うのが generateMetadata です。metadata の代わりに、この名前の関数を export します。
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
return { title: id + " 番の商品 | fleama" };
}受け取るものは、ページを描く関数と同じ params です。第2章でやったとおり await してから中身を取り出します。データベースや API から取ってくる場合は、この関数の中で await fetch(...) を書けます。
戻り値の形は metadata と同じオブジェクトです。つまり「固定なら metadata、URL やデータで変わるなら generateMetadata」という使い分けになります。両方を同じファイルに書くことはできません。
見つからなかったとき
存在しない商品の URL を開かれることもあります。そのときは商品名が取れないので、代わりの文字を返しておきます。
if (!item) return { title: "見つかりません | fleama" };ページ本体で notFound() を呼ぶのと合わせて、タイトルの側も逃げ道を用意しておくと画面と食い違いません。
演習
商品詳細ページに generateMetadata を足して、商品名の入ったタイトルを出します。