メタデータとSEO — generateMetadataでtitle・OGPを動的に設定する
検索結果に表示されるタイトルと説明文、SNSでシェアしたときに出るカード(OGP)——これらは集客を左右する重要な要素です。Next.js(App Router)には、これらを型安全に設定する Metadata API が組み込まれています。
この章では、静的な metadata の設定から、記事ごとに内容を変える generateMetadata、そしてOGPやタイトルテンプレートまでを押さえます。
学習者<head> に <title> や <meta> を書きたいんだけど、App Routerだとどこに書くの?
metadata — 静的なメタデータ
page.tsx または layout.tsx で metadata という名前のオブジェクトを export すると、Next.jsが自動で <head> に反映してくれます。<head> を自分で書く必要はありません。
// src/app/about/page.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "このサイトについて",
description: "私たちのサービスの理念とチームを紹介します。",
};
export default function AboutPage() {
return <h1>このサイトについて</h1>;
}よく使うフィールドは次のとおりです。
| フィールド | 説明 |
|---|---|
title | ページのタイトル(検索結果の見出し・タブの文字) |
description | ページの説明(検索結果のスニペット) |
keywords | キーワード(現在のSEOでは重要度は低い) |
openGraph | SNSシェア時のカード情報(OGP) |
alternates | 正規URL(canonical)など |
先生title と description はSEOの基本中の基本。全ページで「そのページ固有の・内容を表す」文言を必ず設定しよう。使い回しはもったいないよ。

generateMetadata — ページごとに動的なメタデータ
ブログ記事のようにページごとにタイトルが変わる場合、静的な metadata では対応できません。そこで generateMetadata 関数を使います。params を受け取り、データを取得して、メタデータを動的に組み立てられます。
構文: async function generateMetadata({ params }): Promise<Metadata>
| 引数 | 説明 |
|---|---|
params | 動的セグメントの値(第6章と同じ。await で取り出す) |
searchParams | クエリ文字列(必要な場合) |
戻り値: Metadata オブジェクト(title や description など)
// src/app/blog/[slug]/page.tsx
import type { Metadata } from "next";
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>;
}): Promise<Metadata> {
const { slug } = await params;
const post = await fetch(`https://api.example.com/posts/${slug}`).then((r) => r.json());
return {
title: post.title,
description: post.excerpt,
};
}
export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
// ...記事本体の描画
}タイトルのテンプレート — サイト名を自動で付ける
「各ページのタイトル+サイト名」(例:記事タイトル | My Blog)という形にしたいことはよくあります。ルートレイアウトで title.template を設定すると、子ページの title に自動でサイト名が付きます。
// src/app/layout.tsx
export const metadata: Metadata = {
title: {
default: "My Blog", // タイトル未設定のページで使う既定値
template: "%s | My Blog", // %s に各ページのtitleが入る
},
};// src/app/about/page.tsx
export const metadata: Metadata = {
title: "このサイトについて", // → 「このサイトについて | My Blog」になる
};
学習者全ページのタイトルに毎回「| My Blog」って書かなくていいのは助かる…!
OGP — SNSでシェアされたときのカード
SNSでURLが共有されると、openGraph の情報をもとにカード(画像+タイトル+説明)が表示されます。クリック率に直結するため、特に画像(images)は設定しておきたい項目です。
export const metadata: Metadata = {
title: "新サービスを公開しました",
openGraph: {
title: "新サービスを公開しました",
description: "詳しくはこちらをご覧ください。",
images: ["/og/launch.png"], // SNSカードに表示される画像
type: "article",
},
};まとめ
page.tsx/layout.tsxでmetadataをexportすると<head>に自動反映される(<head>は自分で書かない)titleとdescriptionはSEOの基本。全ページで固有の文言を設定する- ページごとに変わるメタデータは
generateMetadata(paramsをawaitして動的生成) - ルートレイアウトの
title.template(%s | サイト名)でサイト名を自動付与できる openGraph.imagesでSNSシェア時のカード画像を設定。sitemap.ts/robots.tsも活用する
次の章では、フォーム送信やデータ更新を扱う Server Actionsとフォーム を学びます。"use server" を使って、APIルートを書かずにサーバー側の処理を呼び出せるようになります。