🎃

Next.js(App Router)のメタタグ設定

2025/02/02に公開

こんにちは。dotD の松村です。

本記事では、Next.js(App Router) でのメタタグの設定方法、特にタイトルのテンプレートの使い方についてお伝えします。

Next.js App Router での Meta タグ設定の基本

Next.js には Metadata API があり、メタデータ(HTML head 要素内の meta タグや link タグなど)を定義して、SEO やウェブ共有性を向上させることができます。
参考:Next.js公式ドキュメント

静的な Meta タグ設定

App Router では、metadata という export を用いて Meta タグを設定します。metadata はオブジェクト形式で、様々な Meta タグの情報を記述します。


// app/layout.tsx (ルートレイアウト)
export const metadata = {
  title: 'My Website',
  description: 'これは私のウェブサイトです',
  keywords: ['Next.js', 'App Router', 'Meta タグ', 'SEO'],
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ja">
      <body>{children}</body>
    </html>
  );
}

上記の例では、title、description、keywords という基本的な Meta タグを設定しています。これらの情報は、検索エンジンの検索結果ページに表示されることがあります。

動的な Meta タグ設定

ページごとに異なる Meta タグを設定したい場合は、generateMetadata という関数を使用します。generateMetadata は、ページコンポーネントの props や context を受け取り、動的に metadata オブジェクトを生成します。


// app/blog/[id]/page.tsx
import { Metadata } from 'next';

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

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const article = await fetch(`/api/articles/${params.id}`).then((res) => res.json());

  return {
    title: article.title,
    description: article.excerpt,
    keywords: article.tags,
  };
}

export default function ArticlePage({ params }: Props) {
  // ...
}

上記の例では、generateMetadata 関数内で記事 ID を取得し、API から記事データを取得しています。そして、取得した記事データに基づいて title、description、keywords を動的に設定しています。

Meta タグの評価順

複数の場所で Meta タグが設定されている場合、Next.js は以下の優先順位で Meta タグを評価します。

  1. ページコンポーネントの metadata
  2. 親レイアウトの metadata
  3. ルートレイアウトの metadata

つまり、より具体的な場所で設定された Meta タグが優先されます。

タイトルにテンプレートを定義する

metadata の title はTemplateStringという型になっています。
TemplateString型は、template, default, absoluteの 3 つの属性を持っています。
このうちtemplate属性とdefault属性を使用することで、Meta タグの共通部分をテンプレートとして定義し、ページごとに異なる部分だけを記述できます。


// app/layout.tsx
export const metadata = {
  title: {
    template: "%s | My Website",
    default: "ブログ一覧",  // テンプレートの %s 部分に 'ブログ一覧' が挿入される
  },
};

// 出力結果: <title>ブログ一覧 | My Website</title>

absolute属性を指定すると、テンプレートを無視した固定のテキストを設定できます。

export const metadata = {
  title: {
    template: "%s | My Website"
    absolute: "ブログ一覧",
  }
}

// 出力結果: <title>ブログ一覧</title>

親ページの meta タグを引き継ぐ

generateMetadata 関数は、引数parentで親ページの Meta データを受け取ることができます。
title 属性で引き継げるのは、templateと、解決後の文字列が入るabsoluteの 2 つです。

export async function generateMetadata(
  { params }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  const article = await fetch(`/api/articles/${params.id}`).then((res) => res.json());

  const parentTitle = (await parent).title // 親ページのタイトルを流用

  return {
    title: {
      template: parentTitle.template,  // 親ページのテンプレートを使用
      default: article.title           // 子ページ固有のタイトルを親ページのテンプレートに当てはめる
    },
    description: article.excerpt, // 子ページ固有の説明文
  };
}

上記の例では、title のテンプレートを親ページで定義し、子ページで title の値を指定しています。これにより、ページごとに異なるタイトルを設定しつつ、共通の接尾辞 (| My Website) を効率的に管理できます。

まとめ

この記事では、Next.js App Router における Meta タグの設定方法について解説しました。
テンプレートを使うことで、効率よくメタタグを管理できるようになります。


弊社では事業創造にチャレンジする仲間を募集中です。
ぜひ採用サイトをご覧いただければ幸いです。

https://dotd-inc.com/ja/careers

dotDTechBlog

Discussion