📝

SEO 面での Gatsby → Next.js 移行ポイント

に公開

こんにちは!アルダグラムでエンジニアをしている柴田です。

最近の Web 開発では SSG(Static Site Generation)を採用するケースがあると思います。SSG の代表的なフレームワークとしては、Gatsby や Next.js が選ばれることが多いと思います(他にもいくつか候補はあると思いますが)。

Web 開発において、SEO は避けて通れない重要な要素です。特に LP や EC サイトなどでは重要な要件になることが多く、その際に重要となるのが SEO 機能の実装難易度・運用コストになるかと思います。

本記事では、Gatsby から Next.js(App Router)への移行という視点で、11 項目の SEO 機能を比較してみました。実装コード付きで、移行時に知っておくべき実装方法の違いや、移行によって得られるメリット・デメリットを明確にしてみました。

※本記事では、Gatsby v5.15.0 および Next.js 16.0.1(App Router)を対象に比較を行っています。

SEO 機能の全体比較

SEO 対応を評価するうえで、どのフレームワークがどの機能をどのレベルでサポートしているかを把握することが重要です。

以下の比較表では、Gatsby と Next.js(App Router)における 11 項目の主要な SEO 機能を一覧化しました。

比較表(全11項目)

SEO機能 Gatsby Next.js(App Router)
Sitemap ✅ プラグイン追加(gatsby-plugin-sitemap ✅ 標準機能(sitemap.tsに記述)
robots.txt ✅ プラグイン追加(gatsby-plugin-robots-txt ✅ 標準機能(robots.tsに記述)
Canonical ✅ プラグイン追加(gatsby-plugin-canonical-urls ⚠️ 各ページで設定(metadata 内で canonical を指定)
hreflang ⚠️ 各ページで設定(Helmetタグ内に記述) ⚠️ 各ページで設定(metadata.alternatesを指定)
メタタグ(title / description / OGP) ⚠️ 各ページで設定(Helmetタグ内に記述) ✅ 標準機能(Metadata APIを用いて実装)
構造化データ(JSON-LD) ⚠️ 各ページで設定(script タグに埋め込む) ⚠️ 各ページで設定(scriptタグに埋め込む)
画像最適化 ✅ プラグイン追加(gatsby-plugin-image ✅ 標準機能(next/image
バンドル最適化 🔧 設定が複雑(Webpackで設定) ✅ 標準機能(自動最適化)
動的 OGP画像生成 ❌ 非対応 ✅  @vercel/ogで対応可能
メタデータ型定義 ❌ 型なし ✅ 標準機能(Metadata APIを用いて実装)

記号の意味

記号 意味
標準機能 または プラグイン追加で対応可能
⚠️ 対応可能だが各ページで個別設定が必要
🔧 対応可能だが、設定が複雑
非対応

比較したところ、SEO面だけでもそれぞれのフレームワークの設計思想の違いが明確に現れていました。Gatsby はプラグインエコシステムで拡張する設計、Next.js は必要な機能を標準で提供する設計となっています。


深掘り解説:Gatsby と Next.js(App Router)の実装の違い

比較表から見えた、各フレームワークの特徴をより詳しく掘り下げていきます。特に差が顕著な 4 つの機能について、実装コード例を交えて解説します。

Metadata / OGP 設定

Gatsbyの場合

動的にメタタグを指定する場合は、各ページに直接タグを埋め込む必要があります。
その際に、 react-helmet がよく用いられます。

import { Helmet } from 'react-helmet';

export default function Page() {
  return (
    <>
      <Helmet>
        <title>ページタイトル</title>
        <meta name="description" content="ページの説明文" />
        <meta property="og:title" content="OG用タイトル" />
        <meta property="og:description" content="OGP用説明文" />
        <meta property="og:image" content="https://example.com/og-image.jpg" />
      </Helmet>
      <div>コンテンツ</div>
    </>
  );
}

📖 Gatsby - Adding an SEO Component

Next.js(App Router)の場合

Metadata APIでオブジェクトとして定義できます。

import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'ページタイトル',
  description: 'ページの説明文',
  openGraph: {
    title: 'OG用タイトル',
    description: 'OGP用説明文',
    images: ['https://example.com/og-image.jpg'],
  },
};

export default function Page() {
  return <div>コンテンツ</div>;
}

定義した metadata は、Next.js が自動的に読み取って HTML の <head> タグ内に変換されます。

上記のコードは、実際には以下のような HTML として出力されます:

<head>
  <title>ページタイトル</title>
  <meta name="description" content="ページの説明文" />
  <meta property="og:title" content="OG用タイトル" />
  <meta property="og:description" content="OGP用説明文" />
  <meta property="og:image" content="https://example.com/og-image.jpg" />
</head>

動的なメタデータも、generateMetadataで簡潔に書けます。

export async function generateMetadata({ params }) {
  const post = await fetch(`/api/sample/${params.id}`);
  
  return {
    title: post.title,
    description: post.description,
    openGraph: {
      images: [post.ogImage],
    },
  };
}

TypeScript の型安全性により、プロパティの誤入力を防げるのも大きな利点です。

📖 Next.js - generateMetadata


画像最適化

Web パフォーマンスに直結する画像最適化は、SEO スコアに大きく影響し、非常に重要な要素です。

Gatsby の場合

Gatsby はビルド時に画像を事前処理するアプローチを採用しています。

gatsby-plugin-image + gatsby-plugin-sharp の複数プラグインに依存し、ビルド時に複数フォーマット・サイズを自動生成します。

import { GatsbyImage, getImage } from 'gatsby-plugin-image';

export default function Page({ image }) {
  const imageData = getImage(image);
  
  return (
    <GatsbyImage
      image={imageData}
      alt="画像の説明"
    />
  );
}

📖 Gatsby - Using gatsby-plugin-image


Next.js(App Router)の場合

ビルトイン機能で外部パッケージが不要です。自動的に WebP 変換、複数サイズ生成、遅延ロードが行われます。

特徴:

  • WebP などの最新フォーマットへの自動変換
  • デバイスサイズに応じた複数サイズの生成
  • 遅延読み込み(lazy loading)がデフォルトで有効
import Image from 'next/image';

export default function Page() {
  return (
    <Image
      src="/image.jpg"
      alt="画像の説明"
      width={800}
      height={600}
      placeholder="blur"
      blurDataURL="data:image/..."
    />
  );
}

📖 Next.js - Image Component


動的 OGP 画像生成

SNS シェア時に、各ページで異なる OGP 画像を生成することで、より高いエンゲージメントが期待できます。また記事タイトルや著者名、日付などを画像に含めることで、シェア時の訴求力の向上も期待できます。

Gatsby の場合

❌ Gatsby では動的な OGP 画像生成がサポートされていないため、事前に用意した静的画像を使用する必要があります。

制限事項:

  • すべてのページで同じ画像を使用するか、各ページ用に事前に画像を作成する必要があります
  • ブログ記事など動的コンテンツの場合、記事ごとの OGP 画像の管理が必要になります
export default function Page() {
  return (
    <>
      <Helmet>
        <meta property="og:image" content="/og-image.jpg" />
      </Helmet>
      <div>コンテンツ</div>
    </>
  );
}

Next.js(App Router)の場合

@vercel/og ライブラリを使用して、各ページごとに動的な OGP 画像を生成できます。API エンドポイントを作成し、ImageResponse を使って画像を返します。

メリット:

  • 各ページのコンテンツに応じた OGP 画像を動的生成
  • デザインの統一性を保ちながら、動的な内容を反映
// app/api/og/route.tsx
import { ImageResponse } from '@vercel/og';

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const title = searchParams.get('title') || 'Default Title';
  
  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          width: '100%',
          height: '100%',
          backgroundColor: '#1a1a1a',
          color: 'white',
        }}
      >
        <h1 style={{ fontSize: 64 }}>{title}</h1>
      </div>
    ),
    {
      width: 1200,
      height: 630,
    }
  );
}

そして、メタタグで上記で定義したエンドポイントを参照します:

<meta 
  property="og:image" 
  content="https://example.com/api/og?title=記事タイトル" 
/>

📖 @vercel/og - OG Image Generation

考察:移行判断のポイント

ここからは、あくまで個人的な見解になります。

Gatsby を継続すべきケース

既存の Gatsby プロジェクトは、移行コストを考慮すると継続運用が無難かもしれません。多くの gatsby-plugin-* に依存している場合、その資産を活かす方が効率的でしょう。

ただし、Gatsby のアップデート頻度は近年やや鈍化傾向にある点は留意しておきたいでしょう(Gatsby GitHub Contributors を参照)。

Next.js (App Router) への移行を検討すべきケース

特に以下のような要件がある場合は、移行によって大きな恩恵を受けられます。

  • SEO 対策の強化が必要(Metadata API による効率的な実装)
  • 動的 OGP 画像生成が必要
  • プラグイン管理の複雑さから脱却したい

ただし、Server Components, Cache Components など新しい概念の学習コストの考慮は必要になるかと思います。

まとめ

Gatsby から Next.js(App Router)への移行を SEO 観点から検証してみました。

比較の結果、Next.js は多くの SEO 機能を標準で提供しており、特に Metadata API による型安全な実装と動的 OGP 画像生成の面で大きなアドバンテージがあることがわかりました。

一方で、既存の Gatsby プロジェクトをすぐに移行すべきかは、プロジェクトの状況次第です。現在安定運用できており、SEO 面で大きな課題がない場合は、移行コストとメリットを慎重に比較検討することが重要です。

個人的には、新規プロジェクトや大規模リニューアルのタイミングであれば、Next.js(App Router)への移行は十分検討に値すると感じました。

ここまでご覧いただきありがとうございました!

参考

Gatsby 関連

Next.js 関連


もっとアルダグラムエンジニア組織を知りたい人、ぜひ下記の情報をチェックしてみてください!

アルダグラム Tech Blog

Discussion