💭

【Next.js】MetaDataの設定の仕方

に公開

この記事では、実際のポートフォリオサイトでの実装例を交えながら、Next.jsのMetadata設定の全体像をまとめています。

基本的なMetadata設定

1. 静的なMetadata設定

最もシンプルな設定方法は、各ページまたはレイアウトでMetadataオブジェクトをexportすることです。

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

export const metadata: Metadata = {
  metadataBase: new URL("https://portfolio.kaze-develop.com/"),
  title: {
    default: "Kaze Portfolio | フロントエンドエンジニアを目指して",
    template: "%s | Kaze Portfolio",
  },
  description:
    "コーダーからフロントエンドエンジニアへ。4年間のコーディング経験を活かし、React/Next.jsでモダンなWeb開発に挑戦するKazeのポートフォリオサイトです。",
  keywords: [
    "Kaze",
    "かぜ",
    "ポートフォリオ",
    "フロントエンドエンジニア",
    "コーダー",
    "React",
    "Next.js",
    "Web制作",
    "HTML",
    "CSS",
    "JavaScript",
    "TypeScript",
  ],
  authors: [{ name: "Kaze" }],
  openGraph: {
    type: "website",
    siteName: "Kaze Portfolio",
    title: "Kaze Portfolio | フロントエンドエンジニアを目指して",
    description: "コーダーからフロントエンドエンジニアへ。React/Next.jsでモダンなWeb開発に挑戦するKazeのポートフォリオサイト。",
    images: [
      {
        url: "/ogp_image.jpg",
        width: 1200,
        height: 630,
        alt: "Kaze Portfolio OGP画像",
      },
    ],
    url: "https://portfolio.kaze-develop.com/"
  },
  twitter: {
    card: "summary_large_image",
    title: "Kaze Portfolio | フロントエンドエンジニアを目指して",
    description: "コーダーからフロントエンドエンジニアへ。React/Next.jsでモダンなWeb開発に挑戦中。",
    images: ["/ogp_image.jpg"],
  },
};

2. 下層ページでのMetadata

下層ページでは、必要な部分のみを上書きできます。レイアウトで設定したtemplateが自動的に適用されます。

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

export const metadata: Metadata = {
  title: "About", // templateが適用され「About | Kaze Portfolio」になる
  description: "Kazeのプロフィールとスキルについて紹介します",
};

export default function AboutPage() {
  return <div>Aboutページ</div>;
}

動的なMetadata生成

CMSやAPIから取得したデータを使って動的にMetadataを生成する場合は、generateMetadata関数を使用します。

app/works/[id]/page.tsx
import { Metadata } from "next";

type Props = {
  params: { id: string };
};

// データ取得関数(例)
async function getWorkDetail(id: string) {
  const res = await fetch(`https://api.example.com/works/${id}`);
  return res.json();
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const work = await getWorkDetail(params.id);
  
  return {
    title: work.title,
    description: work.description,
    openGraph: {
      title: work.title,
      description: work.description,
      images: [
        {
          url: work.thumbnail?.url ?? "/ogp_image.jpg",
          width: work.thumbnail?.width ?? 1200,
          height: work.thumbnail?.height ?? 630,
          alt: work.title ?? "Kaze Portfolio 作品詳細",
        },
      ],
    },
    twitter: {
      card: "summary_large_image",
      title: work.title,
      description: work.description,
      images: [work.thumbnail?.url ?? "/ogp_image.jpg"],
    },
  };
}

export default async function WorkDetailPage({ params }: Props) {
  const work = await getWorkDetail(params.id);
  
  return (
    <article>
      <h1>{work.title}</h1>
      <p>{work.description}</p>
    </article>
  );
}

重要なMetadataプロパティについて

metadataBase

すべての相対URLの基準となるベースURLです。
OGP画像などで相対パスを使用する場合に必須です。

metadataBase: new URL("https://portfolio.kaze-develop.com/"),

title設定

titleには複数の設定方法があります。

title: {
  default: "デフォルトタイトル",
  template: "%s | サイト名", // %sが各ページのtitleに置換される
}

OpenGraph設定

SNSでのシェア時に表示される情報を設定します。

openGraph: {
  type: "website", // または "article"
  siteName: "サイト名",
  title: "OGP用のタイトル",
  description: "OGP用の説明文",
  url: "https://your-domain.com/", // 絶対URLを指定
  images: [
    {
      url: "/ogp_image.jpg",
      width: 1200,
      height: 630,
      alt: "OGP画像の説明",
    },
  ],
},

Twitter Card設定

Twitter(X)でのシェア時の表示形式を設定します。

twitter: {
  card: "summary_large_image", // または "summary"
  title: "Twitter用のタイトル",
  description: "Twitter用の説明文",
  images: ["/ogp_image.jpg"],
},

その他の設定

// 作者情報
authors: [{ name: "作者名" }],

// キーワード(SEO用)
keywords: ["キーワード1", "キーワード2", "キーワード3"],

// 検索エンジンクローラーの制御
robots: "index, follow", // または "noindex, nofollow"

実践的なTips

1. 環境別のmetadataBase設定

app/layout.tsx
const baseUrl = process.env.NODE_ENV === 'production' 
  ? 'https://portfolio.kaze-develop.com/' 
  : 'http://localhost:3000';

export const metadata: Metadata = {
  metadataBase: new URL(baseUrl),
  // その他の設定...
};

2. fallback値の活用

動的生成で、データが取得できない場合のfallback値を用意しておきます。

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const work = await getWorkDetail(params.id);
  
  return {
    title: work?.title || "作品が見つかりません",
    description: work?.description || "作品の詳細情報を取得できませんでした",
    openGraph: {
      images: [
        {
          url: work?.thumbnail?.url ?? "/ogp_image.jpg",
          alt: work?.title || "Kaze Portfolio",
        },
      ],
    },
  };
}

3. OGP画像の最適化

OGP画像は1200x630pxが推奨サイズです。適切なalt属性も設定しましょう。

images: [
  {
    url: "/ogp_image.jpg",
    width: 1200,
    height: 630,
    alt: "サイトの内容を表現する画像の説明",
  },
],

デバッグとテスト

OGPの確認方法

ブラウザでの確認

開発者ツールでHTMLのhead要素を確認し、metaタグが正しく生成されているかチェックできます。

<!-- 生成されるmetaタグの例 -->
<title>About | Kaze Portfolio</title>
<meta name="description" content="Kazeのプロフィールとスキルについて紹介します" />
<meta property="og:title" content="About | Kaze Portfolio" />
<meta property="og:description" content="Kazeのプロフィールとスキルについて紹介します" />

まとめ

Next.js App RouterのMetadata設定により、以下のメリットがあります:

  • 型安全性: TypeScriptによる型チェックでミスを防止
  • 直感的: Head要素の手動管理が不要
  • 柔軟性: 静的・動的両方の設定に対応
  • メンテナンス性: 設定の一元管理が容易

SEOやソーシャルメディア対応において、適切なMetadata設定は必須です。今回紹介した設定例を参考に、あなたのプロジェクトに合わせてカスタマイズしてみてください。

参考リンク

Discussion