発行:

SEO対策(ファイル実装編)

layout.tsx で設定する <head> タグ内の情報だけでなく、SEO には重要なファイルがいくつかあります。
Next.js (App Router) では、 File-based Metadata API と呼ばれる機能により、特定のファイルを置くだけでこれらを自動生成できます。

主な機能は以下の3つです。

  1. Sitemap : sitemap.xml の生成
  2. Robots : robots.txt の生成
  3. Image Response : OGP 画像 (opengraph-image.tsx) などの動的生成

1. サイトマップ (sitemap.xml)

サイトマップは、検索エンジンのクローラーに「私のサイトにはこんなページがありますよ」と伝えるための地図のようなものです。

app/sitemap.ts (または .js) というファイルを作成し、MetadataRoute.Sitemap 型の配列を返す関数をデフォルトエクスポートします。

src/app/sitemap.ts
import { MetadataRoute } from 'next'

export default function sitemap(): MetadataRoute.Sitemap {
  const baseUrl = 'https://example.com'

  return [
    {
      url: baseUrl,
      lastModified: new Date(),
      changeFrequency: 'yearly',
      priority: 1,
    },
    {
      url: `${baseUrl}/about`,
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 0.8,
    },
    {
      url: `${baseUrl}/blog`,
      lastModified: new Date(),
      changeFrequency: 'weekly',
      priority: 0.5,
    },
  ]
}

これで https://your-domain.com/sitemap.xml にアクセスすると、自動的に XML 形式で出力されます。
ブログ記事などの動的なページがある場合は、データベース等から記事一覧を取得して配列に追加すれば OK です。


2. Robots.txt

robots.txt は、クローラーに対して「ここは見ていいよ」「ここは見ちゃダメだよ」と指示するファイルです。

app/robots.ts (または .js) を作成します。

src/app/robots.ts
import { MetadataRoute } from 'next'

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: '*',
      allow: '/',
      disallow: '/private/', // 管理画面などはクロール禁止
    },
    sitemap: 'https://example.com/sitemap.xml',
  }
}

これで https://your-domain.com/robots.txt が生成されます。


3. 動的 OGP 画像 (opengraph-image.tsx)

これが Next.js の非常に強力な機能の一つです。
記事のタイトルを入れた OGP 画像(Twitter カードなどで表示される画像)を、コードだけで生成できます。Photoshop などで一枚ずつ作る必要はありません。

記事の詳細ページ (src/app/blog/[slug]/ など) に opengraph-image.tsx を作成します。

src/app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og'

// 画像のメタデータ(サイズなど)
export const size = {
  width: 1200,
  height: 630,
}
export const alt = 'Blog Post Image'
export const contentType = 'image/png'

// コンポーネントと同じように props から params (slugなど) を受け取れます
export default async function Image({ params }: { params: { slug: string } }) {
  // params.slug を使って記事データを取得する想定
  // const post = await getPost(params.slug)
  const title = `記事のタイトル: ${params.slug}`

  return new ImageResponse(
    (
      // CSSでデザインを書くことができます(Flexbox推奨)
      <div
        style={{
          fontSize: 48,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          color: 'black',
        }}
      >
        {title}
      </div>
    ),
    {
      ...size,
    }
  )
}

これだけで、記事ごとに異なるテキストが入った画像が自動生成され、<head> タグの og:image にも自動的に設定されます。

まとめ

Next.js の File-based Metadata API を使うと、以下のメリットがあります。

  • 自動化 : 手動でファイルを更新する手間が省ける。
  • 動的対応 : 新しい記事を追加しても、サイトマップやOGP画像が自動で作られる。
  • 管理のしやすさ : コードとして管理できるので、Git で履歴が残る。

これらは現代の SEO 対策において「やって当たり前」になりつつある重要な要素です。ぜひ導入してみてください。