Next.js App Router で SEO を強化する
はじめに
Web サイトを公開しても、検索エンジンに正しく認識されなければユーザに届きません。 SEO(Search Engine Optimization) は検索エンジンがサイトの内容を正確に理解し、適切にインデックスするための技術的な基盤です。 Next.js App Router は generateMetadata API や Route Group、Private Folder といった機能を提供しており、SEO に必要なメタデータ管理を効率的に行うことができます。
一方で、Pages Router 時代のテンプレートをベースにしたプロジェクトでは、next/head によるレガシーな SEO 実装が残存しているケースも少なくありません。
今回のブログでは、Next.js App Router における SEO の一般的なプラクティスを紹介しつつ、個人ブログで実施した SEO 強化の内容を紹介したいと思います。
SEO の基本要素
検索エンジンがサイトを評価する際、大きく分けて以下の要素が重要になります。
| 要素 | 説明 |
|---|---|
| sitemap.xml | サイト内の URL 一覧を検索エンジンに伝える |
| robots.txt | クローラのアクセス制御を定義する |
| canonical URL | 同一コンテンツの正規 URL を明示し、重複評価を防ぐ |
| OpenGraph / Twitter Card | SNS でシェアされた際のプレビュー表示を制御する |
| 構造化データ(JSON-LD) | コンテンツの種類や構造を検索エンジンに明示的に伝える |
これらはいずれも検索エンジンにサイトの情報を正しく伝えるためのものです。 コンテンツの質がどれだけ高くても、これらの技術的な基盤が整っていなければ検索結果に正しく反映されません。
SEO 強化で実施したこと
robots.txt の設置
robots.txt はクローラに対してアクセス制御を定義するファイルです。 public/robots.txt に配置すると、サイトルートの /robots.txt として配信されます。
インデックスさせたくないページ(iframe 埋め込み専用ページ等)は Disallow で指定します。 加えて、Sitemap ディレクティブで sitemap.xml の場所を明示しておくと、クローラが効率的に URL を発見できます。
sitemap.xml の修正
sitemap.xml は検索エンジンにサイト内の URL 一覧を伝えるためのファイルです。 Google は sitemap.xml を参照してクロール対象の URL を把握します。
Next.js App Router では、Route Group (site) や Private Folder _components がファイルシステム上に存在するため、単純に app/**/page.tsx を glob しただけでは不正な URL が生成されます。
これらの URL は実際にはアクセスできず、検索エンジンの クロールバジェット を浪費します。 クロールバジェットとは、Googlebot が一定期間内にサイトをクロールする URL 数の上限です。 不正な URL が sitemap に含まれていると、クローラが本来インデックスすべきページに到達しにくくなるため、sitemap の品質はインデックス効率に直結します。
App Router で sitemap を生成する際は、例えば以下のようなフィルタリングが必要になります。
静的ページの glob だけでは動的ルートの実 URL(個別のブログ記事やスライドページ等)が含まれません。 コンテンツのデータソース(MDX ファイルや YAML 等)から実際の slug を読み取り、URL を動的に生成して sitemap に追加する必要があります。
全ページへの metadata 追加
Next.js App Router では、generateMetadata 関数または export const metadata で各ページのメタデータを定義します。
SEO 上、全ページに以下のメタデータを設定することが推奨されます。
- canonical URL:同一コンテンツの正規 URL。検索エンジンの重複評価を防ぐ
- OpenGraph:Facebook や Slack 等でシェアされた際のプレビュー表示
- Twitter Card:X(旧 Twitter)でシェアされた際のプレビュー表示
静的ページでは export const metadata を使用します。
動的ページ(ブログ記事、タグページ等)では generateMetadata 関数でパラメータに応じたメタデータを返します。
また、root layout(app/layout.tsx)にデフォルトの OpenGraph / Twitter Card / robots ディレクティブを定義しておくと、個別ページで上書きしない限りデフォルト値が適用されるため、設定漏れのリスクを低減できます。
max-image-preview: large と max-snippet: -1 を設定することで、Google 検索結果でのリッチスニペット表示を最大化しています。
構造化データ(JSON-LD)の追加
通常の HTML メタタグだけでは、検索エンジンはページの内容をテキストから推測するしかありません。 構造化データは schema.org の語彙を使って「このページはブログ記事で、著者は〇〇、公開日は〇〇」といった情報を機械可読な形式で明示します。
これにより、Google 検索結果でリッチリザルト(著者名、公開日、サムネイル画像等が表示される特別な検索結果)の対象になります。 リッチリザルトは通常の検索結果よりも視覚的に目立つため、クリック率(CTR)の向上が期待できます。 Google の Search Gallery で、構造化データによって実現できるリッチリザルトの種類を確認できます。
ブログ記事ページには Article スキーマ を generateMetadata 内で出力します。
レガシー SEO 実装の廃止
Pages Router テンプレートをベースにしたプロジェクトでは、next/head を使った SEO コンポーネントが残存しているケースがあります。
- Pages Router 時代のレガシー実装
App Router の generateMetadata と next/head の両方が OGP メタタグを出力している場合、メタデータが重複します。 next/head による実装を完全に廃止し、generateMetadata に一本化することで、メタデータの管理を統一できます。
Google Search Console への登録
技術的な SEO 基盤を整えた後、Google Search Console にサイトを登録します。 Search Console は Google がサイトをどのように認識しているかを確認できるツールで、インデックスの状況やクロールエラーの確認が可能です。
登録手順は以下の通りです。
- Google Search Console にアクセスし、「URL プレフィックス」にサイト URL を入力
- DNS TXT レコードによる所有権確認(
google-site-verification=...) - 左メニュー「サイトマップ」から sitemap.xml の URL を送信
- 「URL 検査」から主要ページのインデックス登録をリクエスト
DNS レコードは Terraform 等の IaC ツールで管理すると、設定の追跡や変更管理が容易になります。
Next.js App Router における SEO 実装
generateMetadata による一元管理
App Router で SEO メタデータを管理する方法は generateMetadata に統一されています。 Pages Router の next/head や next-seo パッケージを併用する必要はありません。
この例では、root layout でデフォルト値を定義し、各ページで必要に応じて上書きするレイヤ構造になっています。 これにより、新しいページを追加した際に OG や Twitter Card の設定を忘れても、デフォルト値が適用されます。
sitemap 生成スクリプトの設計
App Router のファイルシステムには Route Group (site) や Private Folder _components が存在するため、sitemap 生成スクリプトでは例えば以下の考慮が必要になります。
| 考慮事項 | 対策 |
|---|---|
Route Group (site) が URL に含まれる | 正規表現で除去する |
動的ルート [slug] がリテラル出力される | [ を含むパスを除外する |
_components が URL に含まれる | _components を含むパスを除外する |
| embed ページが含まれる | (embed) を含むパスを除外する |
| 動的ルートの実 URL が含まれない | コンテンツデータソースから slug を読み取り動的生成 |
| 下書き記事が含まれる | 下書きフラグのある記事を除外する |
静的ページの glob + コンテンツデータからの動的生成を組み合わせることで、正確な sitemap を出力できます。
まとめ
Next.js App Router における SEO の要点は、generateMetadata によるメタデータの一元管理と、App Router 固有のファイルシステム構造を考慮した sitemap 生成にあります。 Pages Router から移行したプロジェクトでは next/head によるレガシー実装が残りやすいため、generateMetadata への一本化を早めに進めておくと管理が楽になります。
また、root layout でデフォルトの OpenGraph / Twitter Card を定義しておくことで、新しいページを追加した際の設定漏れを防ぐことができます。
技術的な SEO 基盤は検索エンジンに正しくインデックスしてもらうための前提条件です。 コンテンツの質や被リンクが検索順位に大きく影響しますが、前提条件が満たされていなければそもそも土台に乗りません。