Dev Study
← 解説「metadata — ページのタイトルとSEO」に戻る

サンプルコードで身につける: metadata — ページのタイトルとSEO

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1最小の metadata

title だけを設定する metadata の最小形です。オブジェクトをエクスポートするだけで head 内の title タグが生成され、ブラウザのタブの表示が変わります。まずはこの1項目から始めましょう。

// app/page.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "My Site — ホーム",
};

export default function HomePage() {
  return <h1>ようこそ</h1>;
}

// 生成される HTML(head 内):
// <title>My Site — ホーム</title>
// ブラウザのタブにこの文字が表示される。

2タイトルと説明文のセット

title と description をページごとに設定する、SEO の基本形です。description は検索結果でタイトルの下に出る紹介文の候補になるため、ページの内容を1〜2文で要約して書くのが実務の作法です。

// app/pricing/page.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "料金プラン | My Service",
  description:
    "My Service の料金プランのご案内。無料プランから法人向けプランまで、用途に合わせて選べます。",
};

export default function PricingPage() {
  return <h1>料金プラン</h1>;
}

// description は検索結果の「紹介文」の候補として使われる。

3layout で title のテンプレートを作る

layout.tsx に template を書くと、各ページは固有部分だけを書けば「ページ名 | サイト名」の形に自動で揃います。全ページのタイトルの統一感を1か所で管理できる、サイト全体の SEO 設定の土台です。

// app/layout.tsx — サイト全体のタイトル規則を1か所で決める
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: {
    template: "%s | My Site", // %s に各ページの title が入る
    default: "My Site", // title を書かないページで使われる
  },
  description: "My Site の公式サイトです。",
};

// ─────────────────────────────
// app/about/page.tsx — 固有部分だけ書けばよい
export const metadata = { title: "About" };
// → <title>About | My Site</title> になる

4テンプレートの解決を再現する

「%s | My Site」というテンプレートに各ページのタイトルが埋め込まれる解決の流れを、プレーンな TypeScript で実行する例です。title を持たないページで default が使われる、という分岐も合わせて確かめられます。

TypeScript

5記事ごとの generateMetadata とOG設定

動的ルートでは記事ごとにタイトルが違うため、generateMetadata という async 関数で params からデータを引いてメタデータを組み立てます。openGraph を添えると SNS シェア時のカード表示まで整う、ブログ実務の完成形です。

// app/blog/[id]/page.tsx — 記事ごとに違うメタデータを作る
import type { Metadata } from "next";

export async function generateMetadata({
  params,
}: {
  params: Promise<{ id: string }>;
}): Promise<Metadata> {
  const { id } = await params;
  const res = await fetch("https://api.example.com/posts/" + id);
  const post = await res.json();

  return {
    title: post.title + " | My Blog",
    description: post.summary,
    openGraph: {
      title: post.title, // SNS シェア時のカードに使われる
      description: post.summary,
    },
  };
}

export default async function PostPage() {
  return <article>{/* 記事本文 */}</article>;
}