Next.jsのSEO ― App RouterのMetadata APIで正しく設定する
投稿日:2026.06.14
CATEGORY
- Web開発
next/headを手書きする時代から変わった
Pages Routerの時代、Next.jsでメタタグを設定するには各ページでnext/headを使ってHTMLタグを手書きするのが一般的でした。App Routerが登場した後、Next.js 13.2.0からMetadata APIが追加され、メタタグの管理方法が大きく変わりました。
この記事では、App RouterのMetadata APIを中心に、SEOに必要な設定を実装者向けに解説します。内容はNext.js公式ドキュメント(App Router前提)に基づいています。
Metadata APIの基本構造
App RouterのMetadata APIでは、layout.tsxまたはpage.tsxからmetadataオブジェクト(静的な場合)またはgenerateMetadata関数(動的な場合)をexportします。
静的なmetadata
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'ページタイトル',
description: 'ページの説明文',
}
動的なgenerateMetadata
URLパラメータやデータベースの値に応じてメタタグを変えたい場合はgenerateMetadataを使います。
import type { Metadata } from 'next'
type Props = {
params: Promise<{ slug: string }>
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params
// DBやAPIからデータを取得してメタタグを生成
return {
title: `記事タイトル - ${slug}`,
}
}
重要な制約: metadataとgenerateMetadataはServer Component専用です。'use client'を付けたClient Componentでは使えません。また、同一セグメント(同じpage.tsx)で両方を同時にexportすることはできません。
最低限設定すべき5つの項目
1. metadataBase
metadataBaseはルートのlayout.tsxに設定します。OGP画像URLやcanonicalに相対パスを使う場合、この設定がないとエラーになります。
export const metadata: Metadata = {
metadataBase: new URL('https://example.com'),
}
本番環境のURLを環境変数で管理するのが一般的です。
metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL ?? 'https://example.com'),
2. title
titleにはtemplateとdefaultを使うことで、サイト共通のタイトル書式を一箇所で管理できます。
// app/layout.tsx(ルート)
export const metadata: Metadata = {
title: {
template: '%s | サイト名',
default: 'サイト名',
},
}
// app/blog/[slug]/page.tsx
export const metadata: Metadata = {
title: '記事タイトル', // → "記事タイトル | サイト名" になる
}
テンプレートを使わずそのままのタイトルにしたい場合はabsoluteを使います。
title: { absolute: 'このタイトルそのまま使う' }
3. description
meta descriptionはページごとにユニークな内容を設定します。Googleが書き換える場合がありますが、設定しておくことで検索結果の表示を意図に近づけられます。
4. canonical(alternates)
同一コンテンツが複数URLで表示される場合にcanonoical URLを指定します。
export const metadata: Metadata = {
alternates: {
canonical: '/blog/this-article',
},
}
metadataBaseが設定されていれば、相対パスが絶対URLに自動解決されます。
多言語対応が必要な場合はhreflangもalternates.languagesで設定できます。
5. openGraph
OGPはSNSでシェアされた時の表示に影響します。
export const metadata: Metadata = {
openGraph: {
title: 'OGP用タイトル',
description: 'OGP用説明文',
images: [{
url: '/og-image.png', // metadataBaseが必要
width: 1200,
height: 630,
}],
},
}
画像URLには絶対URLが必要です。metadataBaseを設定してあれば相対パスで書けます。
よくある落とし穴
openGraphは「deep merge」ではない
子セグメントでopenGraphを部分的に設定すると、親のopenGraphの全フィールドが上書き消去されます。
// 親(app/layout.tsx)
export const metadata: Metadata = {
openGraph: {
siteName: 'サイト名',
images: [{ url: '/default-og.png' }],
},
}
// 子(app/blog/page.tsx) — 意図しない結果になる
export const metadata: Metadata = {
openGraph: {
title: 'ブログ一覧',
// siteName と images が消える!
},
}
共通フィールドを引き継ぎたい場合は、spread演算子で明示的に展開します。
import { sharedOpenGraph } from '@/lib/metadata'
export const metadata: Metadata = {
openGraph: {
...sharedOpenGraph,
title: 'ブログ一覧',
},
}
Client ComponentではMetadata APIは使えない
インタラクティブなUIと同じファイルにメタタグを設定したい場合は、Server Componentとして別ファイルに切り出すか、layout.tsxで設定します。
viewportとthemeColorの非推奨化
Next.js 14以降、viewportとthemeColorはMetadata APIのmetadataオブジェクトでは非推奨になりました。代わりにgenerateViewportを使います。
import type { Viewport } from 'next'
export const viewport: Viewport = {
themeColor: '#ffffff',
width: 'device-width',
initialScale: 1,
}
動的OG画像の生成
appディレクトリにopengraph-image.tsxを配置すると、ImageResponseを使って動的なOGP画像を生成できます。記事ごとにタイトルを入れたOGP画像を自動生成する場合に便利です。
// app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og'
export default async function Image({ params }: { params: { slug: string } }) {
return new ImageResponse(
<div style={{ display: 'flex', fontSize: 40 }}>
{params.slug}
</div>
)
}
Google Search Console所有確認の設定
GSCでサイトの所有確認をメタタグで行う場合はverificationを使います。
export const metadata: Metadata = {
verification: {
google: 'xxxxxxxxxx', // GSCで発行されたコード
},
}
Pages Routerとの違い
Pages Routerを使っているプロジェクトでは、Metadata APIは使えません。Pages Routerでは引き続きnext/headを使ってメタタグを設定します。app/sitemap.tsなどのファイル規約もApp Router専用です。Pages RouterプロジェクトをApp Routerに移行する際は、next/headの記述をMetadata APIに置き換える作業が必要になります。
ここまでをまとめると
App RouterのMetadata APIを使うことで、メタタグの設定を宣言的・型安全に管理できます。実装時に特に意識すべき点は次のとおりです。
- metadataBase: ルートlayoutに必ず設定する。OGP画像とcanonicalの相対パス解決に必要
- title.template: サイト名の付与ルールを一箇所で管理する
- openGraph: 子セグメントで設定すると親フィールドが消える。共通値はspreadで引き継ぐ
- viewport / themeColor: Next.js 14以降は
generateViewportを使う - Client Component:
'use client'のファイルではMetadata APIは使えない
keywordsメタタグはGoogleが無視するため、設定しても検索順位への影響はありません。その時間を、コンテンツの質やCore Web Vitalsの改善に充てる方が実効性があります。
出典
- Next.js Metadata API リファレンス(generateMetadata): https://nextjs.org/docs/app/api-reference/functions/generate-metadata
- Next.js Metadata and OG images: https://nextjs.org/docs/app/api-reference/file-conventions/metadata

