昨年、34,000ページのEコマースサイトをモノリシックなWordPressインストレーションからNext.jsとヘッドレスCMSを使用したヘッドレスアーキテクチャに移行しました。クライアントのオーガニックトラフィックは収益の72%を占めていました。プレッシャーは相当なものでした。

移行には14週間の計画と6週間の実行期間がかかりました。切り替え後、1週目のオーガニックトラフィックは3.2%低下し、3週目までに回復し、2か月目には11%上昇していました。これは運ではなく、プロセスです。

移行が大失敗するのを見たことがあります。同じクライアントの競合他社は6か月前に移行し、一夜にしてオーガニックトラフィックの40%を失いました。8か月後でも、まだ回復していませんでした。大規模移行の成功と災害の違いは、準備、リダイレクト管理、そして実際に信頼できるロールバックプランを持っているかによって決まります。

この記事では、数万ページを持つサイトを移行するときに行うすべてのことを説明します。WordPressからNext.jsへ、DrupalからAstroへ、またはその他のプラットフォームシフトに移行するかどうかにかかわらず、同じプロセスです。

目次

30,000ページのウェブサイトをSEOを失わずに移行する方法

大規模移行が失敗する理由

ほとんどの移行の失敗は同じ根本原因を共有しています。事前にこれらを理解することで、失敗したローンチの墓場に入ることを避けることができます。

リダイレクトの問題

500ページのサイトでは、すべてのURLを手動でマッピングできます。30,000ページのサイトでは、できません。チームは90%のURLをカバーする正規表現ベースのリダイレクトルールを書き、残りの10%は自動的に解決されるだろうと仮定しています。残りの10%?それは3,000ページです。その多くはあなたの最高パフォーマンスコンテンツです。

2025年のAhrefsの調査では、移行中に索引付きページの15%以上を失ったサイトは、平均してオーガニックトラフィックが34%低下し、回復には平均4〜8か月かかることが判明しました。

パリティの問題

Googleはコンテンツだけを気にするわけではなく、構造を気にします。内部リンクパターン、見出し階層、構造化データ、カノニカルタグ、ページネーション処理、ファセットナビゲーション。これらの多くを同時に変更すると、Googleは本質的にサイト全体をゼロから再評価する必要があります。

タイミングの問題

チームが何か月も新しいサイトを完璧にするのに費やし、リーダーシップが無耐心になったため実際の移行を急ぐケースを見たことがあります。30,000ページのサイトを金曜日午後に移行することはありません。ピークトラフィック期間中に移行することはありません。実際に信頼できるロールバックプランがなく移行することは絶対にありません。

フェーズ1: 移行前監査とクロール

何かに触れる前に、今日存在するものの完全な概要が必要です。これがあなたのベースラインであり、移行全体を通じて常にそれを参照します。

フルサイトクロール

Screaming Frog、Sitebulb、またはLumar(旧Deepcrawl)などのクラウドベースのクローラーを使用して完全なクロールを実行します。30,000ページ以上のサイトの場合、クラウドオプションが必要です。デスクトップクローラーはこのサイズでは機能しなくなり、クロールデータがチーム全体で共有可能である必要があります。

すべてをキャプチャします:

  • すべてのURLとそのHTTPステータスコード
  • タイトルタグとメタディスクリプション
  • H1タグ
  • カノニカルタグ
  • hreflangタグ(該当する場合)
  • ページごとの内部リンク(インバウンドとアウトバウンド)
  • 現在の構造化データタイプ
  • ページロード時間
  • ページごとの単語数
  • 画像とalt属性

分析ベースライン

過去12か月のGoogle AnalyticsデータとGoogle Search Consoleデータをエクスポートします。以下が必要です:

  • オーガニックセッション別の上位1,000ランディングページ
  • クリック数とインプレッション数別の上位5,000クエリ
  • クロール統計(1日あたりのクロール済みページ数、応答時間)
  • Core Web Vitalsスコア
  • インデックスカバレッジレポート(インデックス済み、除外、エラー)

オーガニックランディングページの上位500をタグ付けします。これらは壊れてはならないページです。期間。移行中および移行後に、これらのページのすべてが個別に検証されます。

バックリンク監査

Ahrefs、Semrush、Google Search Consoleからバックリンクデータを取得します。相互参照して、それを指すすべてのURLを指すすべての外部リンクを見つけます。これらのURLは完璧な301リダイレクトが必要です。高権限ページでのバックリンク資産を失うことは、ランキングを失う最も速い方法の1つです。

# 例: エクスポートとバックリンク済みURLの重複排除
ahrefs-export.csv + semrush-export.csv + gsc-export.csv
| sort -u 
| awk -F',' '{print $1}' 
> unique_backlinked_urls.txt

wc -l unique_backlinked_urls.txt
# 出力: 8,247個のバックリンク付きユニークURL

フェーズ2: URLマッピングとリダイレクト戦略

これは移行が勝利または敗北するところです。30,000ページのサイトでは、自動マッピングを重要なページの手動検証と組み合わせた体系的なアプローチが必要です。

リダイレクトマップの構築

URLを パターンごとにカテゴリ分けしましょう。ほとんどの大規模サイトには、ページの大多数を占める比較的少数のURLパターンがあります:

URLパターン ページ数 戦略
製品ページ /products/blue-widget-123 18,000 Regex + IDマッピング
カテゴリページ /category/widgets 450 手動マッピング
ブログ記事 /blog/2024/03/post-title 3,200 スラッグ保持
タグ/フィルターページ /products?color=blue 6,500 評価: リダイレクトまたはnoindex
スタティックページ /about, /contact 85 手動マッピング
ページネーション済みページ /category/widgets/page/3 1,800 新しいページネーションにマップ

3段階アプローチ

段階1: 手動マッピング(上位500ページ) あなたの最高トラフィック、最高収益ページは個別にマッピングされます。人間がそれぞれのリダイレクトを検証します。例外はありません。

段階2: パターンベースのマッピング(次の約25,000ページ) 古いURLパターンを新しいパターンに変換する変換ルールを書きます。デプロイ前に、完全なURLリストに対してこれらのルールをテストします。

# リダイレクトルール生成の例
import csv
import re

def generate_redirect(old_url):
    # 製品ページ: /products/blue-widget-123 -> /shop/blue-widget
    product_match = re.match(r'/products/([a-z-]+)-(\d+)$', old_url)
    if product_match:
        slug = product_match.group(1)
        return f'/shop/{slug}', 301
    
    # ブログ記事: /blog/2024/03/post-title -> /blog/post-title
    blog_match = re.match(r'/blog/\d{4}/\d{2}/(.+)$', old_url)
    if blog_match:
        slug = blog_match.group(1)
        return f'/blog/{slug}', 301
    
    return None, None

# すべてのURLを処理
with open('all_urls.csv') as f:
    reader = csv.reader(f)
    unmapped = []
    for row in reader:
        old_url = row[0]
        new_url, status = generate_redirect(old_url)
        if new_url is None:
            unmapped.append(old_url)
    
    print(f"マップされていないURL: {len(unmapped)}")

段階3: 残りのマップされていないページ(約4,500ページ) これはあなたのエッジケースです。手動で確認します。意図的に廃止されるページもあります(最も関連するページにリダイレクト)。トラフィックまたはバックリンクを持っていたページで404を残しません。

リダイレクトチェーンとループ

古いサイトに既にリダイレクトが存在する場合、新しいリダイレクトはチェーン(A → B → C)を作成する可能性があります。ローンチ前にこれらを解決します。すべてのリダイレクトは、単一のホップで古いURLから最終目標に直接進む必要があります。リダイレクトチェーンはPageRankを失います。GoogleのJohn Muellerは、チェーンに従うことはできますが、直接リダイレクトは常に優先されることを複数回確認しています。

30,000ページのウェブサイトをSEOを失わずに移行する方法 - アーキテクチャ

フェーズ3: 技術的SEO同等性チェックリスト

新しいサイトは古いサイトとの技術的なSEOパリティを維持する必要があります。理想的には改善する必要があります。以下は、チェックする内容です:

重要なパリティ項目

  • タイトルタグ: 同じまたは改善。移行中に空白のままにしないでください。
  • メタディスクリプション: 再作成を計画しても、それらを引き継ぎます。
  • H1構造: ページあたり1つのH1で、古いサイトのキーワードターゲティングに一致します。
  • カノニカルタグ: すべてのページで自己参照カノニカル。古いサイトがクロスドメインカノニカルを持っていた場合、それらを保持します。
  • Robots.txt: ローンチ時にGoogleBotを誤ってブロックしないでください。これが起こるのは私が好むより多くあります。
  • XMLサイトマップ: すべての新しいURLで新しいサイトマップを生成します。ローンチ後数時間以内に送信します。
  • 構造化データ: すべてのスキーママークアップを移行します。製品スキーマ、FAQスキーマ、パンくずスキーマ - すべてです。
  • 内部リンク: 新しいサイトの内部リンクグラフは、古いサイトのグラフを密接に反映する必要があります。

パフォーマンス要件

GoogleのCore Web Vitalsはランキング要因です。新しいサイトは古いサイトのパフォーマンスに対して対等またはそれ以上である必要があります:

メトリック 良好な閾値 ターゲット
LCP(最大含有量塗料) ≤ 2.5s ≤ 2.0s
INP(次のペイントへの相互作用) ≤ 200ms ≤ 150ms
CLS(累積レイアウトシフト) ≤ 0.1 ≤ 0.05
TTFB(最初のバイトまでの時間) ≤ 800ms ≤ 400ms

これは、Next.jsやAstroのような最新のスタックへの移行が実際に利点をもたらす1つの領域です。静的生成とエッジレンダリングはTTFBを大幅に改善できます。従来のWordPressからNext.jsを使用したISRまたはAstroを使用した静的出力に移動する場合、TTFBが1.2秒から200ms以下に低下するのを見てきました。

フェーズ4: コンテンツ移行と検証

自動コンテンツ抽出

30,000ページの場合、自動コンテンツ抽出が必要です。通常、新しいヘッドレスCMSにインポートする前に、カスタムスクレーパーまたはCMSのエクスポートAPIを使用してコンテンツを構造化形式(通常はJSONまたはCSV)に引き出します。

インポート後の主要な検証:

  • 文字エンコーディング(壊れた特殊文字を監視)
  • 画像参照(すべての画像が解決されるか?)
  • 内部リンク(新しいURLパターンに更新されているか?)
  • 埋め込みメディア(ビデオ、iframe、ウィジェット)
  • テーブルフォーマット
  • コードブロック

コンテンツ差分テスト

上位500のURLについて、古いページと新しいページの自動比較を実行します。このスクリプトは両方のバージョンをフェッチし、HTMLを削除し、テキストコンテンツを比較します。テキストの類似性が95%未満のページはすべてフラグが立てられ、手動レビューのためマークされます。

// 簡略化されたコンテンツ比較
const { diff } = require('fast-diff');
const cheerio = require('cheerio');

async function comparePages(oldUrl, newUrl) {
  const oldHtml = await fetch(oldUrl).then(r => r.text());
  const newHtml = await fetch(newUrl).then(r => r.text());
  
  const oldText = cheerio.load(oldHtml)('main').text().trim();
  const newText = cheerio.load(newHtml)('main').text().trim();
  
  const changes = diff(oldText, newText);
  const unchanged = changes
    .filter(([type]) => type === 0)
    .reduce((sum, [, text]) => sum + text.length, 0);
  
  const similarity = unchanged / Math.max(oldText.length, newText.length);
  
  return {
    similarity: Math.round(similarity * 100),
    oldLength: oldText.length,
    newLength: newText.length,
    needsReview: similarity < 0.95
  };
}

フェーズ5: ステージング環境テスト

徹底的なステージングテストなしに移行をローンチしないでください。検証する内容は以下の通りです:

リダイレクトテスト

すべてのリダイレクトをテストしてください。はい、30,000個すべてです。リダイレクトチェーンをフォローし、最終宛先を検証するスクリプトを使用します:

# マッピングファイルからのリダイレクトをテスト
while IFS=, read -r old_url new_url; do
  response=$(curl -s -o /dev/null -w "%{http_code} %{redirect_url}" "$old_url")
  status=$(echo $response | cut -d' ' -f1)
  redirect=$(echo $response | cut -d' ' -f2)
  if [ "$status" != "301" ] || [ "$redirect" != "$new_url" ]; then
    echo "FAIL: $old_url -> $status $redirect (expected 301 $new_url)"
  fi
done < redirect_map.csv

レンダリング検証

クライアント側レンダリング(CSR)またはハイドレーション集約的なアプローチを使用している場合、GoogleBotが実際にコンテンツを表示できることを確認してください。GoogleのリッチリザルトテストまたはSearch ConsoleのURL検査ツールを使用して、レンダリングされた出力をチェックします。

これは特にReactベースのフレームワークの一般的な問題です。コンテンツがレンダリングするにはJavaScriptが必要で、SSRまたはSSGを適切に実装していない場合、Googleは空白ページを表示する可能性があります。常にSEO重要なページにはサーバー側レンダリングまたは静的生成を使用します。

フェーズ6: ローンチ日の実行

ローンチチェックリスト

  1. DNS TTL: 移行の少なくとも48時間前にDNS TTLを300秒に低下させます
  2. リダイレクトをデプロイ: すべての301リダイレクトを古いサーバー/CDNにしましょう
  3. DNSを切り替え: ドメインを新しいインフラストラクチャにポイントします
  4. リダイレクトを確認: 本番環境に対して自動リダイレクトテストを実行します
  5. サイトマップを送信: Google Search Consoleで新しいXMLサイトマップを送信します
  6. インデックス作成をリクエスト: URL検査ツールを使用して上位50ページのインデックス作成をリクエストします
  7. 監視: リアルタイム分析で異常を監視します
  8. robots.txtを確認: GoogleBotがブロックされていないことを確認します
  9. CDN/キャッシング確認: リダイレクトヘッダーが誤ってキャッシュされていないことを確認します

タイミング

火曜日または水曜日の朝にローンチします。金曜日はありません。週末前に少なくとも3営業日フルで監視し、問題を修正できるようにしたいです。ピークトラフィック期間やメジャーショッピングイベント中は移行を避けます。

ローンチ後の夜間も誰かが監視していることを確認します。Googleはオフピーク時間中により積極的にクロールすることが多く、リダイレクトに問題がある場合は、迅速にそれをキャッチしたいです。

ロールバックプラン

15分以内に実行できるテスト済みのロールバックプランを用意します。これは通常、移行後少なくとも2週間のために古いインフラを並行して実行し続けることを意味します。2つの環境を一時的に維持するコストは、失敗した移行のコストと比べて何もありません。

フェーズ7: 移行後の監視

日次監視(1〜2週目)

  • クロールエラー: Google Search Consoleで新しい404とサーバーエラーを毎日確認します
  • インデックスカバレッジ: インデックスカバレッジレポートで低下を監視します
  • オーガニックトラフィック: 日次のオーガニックセッションをベースラインと比較します
  • ランキング: 上位200キーワードを毎日追跡します
  • サーバーログ: 新しいサイト上でのGoogleBotのクロールパターンを分析します
  • Core Web Vitals: フィールドデータが入って来始めたら検証します

週次監視(3〜8週目)

  • オーガニックトラフィックを週対週で比較
  • ランキングの変動を監視
  • 新しいクロール問題を確認
  • リダイレクトチェーンが誤って作成されていないことを検証
  • バックリンクプロファイルで失われたリンクを監視

予想されるトラフィックパターン

よく実行された移行は通常以下を示します:

  • 1週目: 5-15%のトラフィック低下(Googleは変更を処理しています)
  • 2〜3週目: 移行前のレベルへの回復
  • 4〜8週目: 新しいサイトが技術的に優れている場合、多くの場合トラフィック増加が見られます

回復しない30%以上の低下が見られた場合、リダイレクトまたは技術実装で何か問題が発生しました。すぐにSearch Consoleを掘り下げます。

大規模なリダイレクト実装

リダイレクトをどこに実装するかが重要です。30,000以上のリダイレクトを.htaccessファイルまたはNext.jsのredirects設定配列に詰め込まないでください。パフォーマンスを殺します。

推奨アプローチ

エッジレベルのリダイレクト(パフォーマンスに最適) Cloudflare Workers、Vercel Edge Middleware、またはNetlifyの_redirectsファイルを使用して、エッジ/CDNレベルでリダイレクトを実装します。エッジリダイレクトはアプリケーションコードの前に実行されるため、非常に高速です。

// Vercel Edge Middlewareの例
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

// リダイレクトマップをロード(デプロイ時に事前構築)
import redirectMap from './redirects.json';

export function middleware(request: NextRequest) {
  const path = request.nextUrl.pathname;
  const redirect = redirectMap[path];
  
  if (redirect) {
    return NextResponse.redirect(
      new URL(redirect.destination, request.url),
      redirect.permanent ? 301 : 302
    );
  }
  
  return NextResponse.next();
}

データベースベースのリダイレクト(柔軟性に最適) リダイレクトをデータベースに保存し、リクエスト時にそれらを検索します。これにより、再デプロイしなくてもリダイレクトを追加、変更、監査できます。積極的なキャッシング(Redisまたは同様のもの)を追加して、データベース検索がレイテンシを追加しないようにします。

ハイブリッドアプローチ(通常行うこと) パターンベースのリダイレクトをエッジで、個別リダイレクトをデータベースで。両方の長所を備えています。

国際およびマルチ言語サイトの処理

30,000ページのサイトに複数の言語またはリージョンが含まれる場合、複雑性が乗算されます。各言語バージョンは独自のリダイレクトマップが必要です。Hreflangタグを新しいURLを参照するように更新する必要があります。また、Search Consoleでの言語/リージョンターゲティングが引き続き正常に機能することを検証する必要があります。

一般的な落とし穴:

  • すべての言語バージョン全体でhreflang注釈を同時に更新するのを忘れる
  • hreflang相互要件を破る(ページAがページBを指す場合、ページBはページAを指す必要があります)
  • Googleが信号として使用する言語固有のURL構造を失う

ランキングを殺す一般的な誤り

  1. 301の代わりに302を使用: 一時的なリダイレクトは完全なリンク資産を渡しません。リダイレクトステータスコードを3回確認します。
  2. ステージングサイトをブロックし、ブロック解除を忘れる: ステージングのあなたのrobots.txtDisallow: /と言います。ステージングを本番環境にデプロイします。GoogleBotは何もクロールできません。
  3. コンテンツとURLを同時に変更: Googleは新しいURLで異なるコンテンツを表示します。これは新しいページですか?移動されたページですか?曖昧さを減らします。最初にURLを移行し、その後コンテンツを変更します。
  4. すべてをホームページにリダイレクト: 怠け者のリダイレクト実装は、すべての古いURLをホームページに送信し、ロングテールランキングを即座に破壊します。
  5. JavaScriptレンダリングを無視: 新しいReactアプリはChromeで素晴らしく見えます。GoogleBotは空の<div id="root"></div>を見ます。
  6. 末尾スラッシュを一貫して処理しない: /products/widget/products/widget/は異なるURLです。1つを選んで、もう1つをリダイレクトします。
  7. リダイレクトなしでページを削除: ページにトラフィックがあった場合、リダイレクトが必要です。そのコンテンツを廃止している場合でも、最も関連するページにリダイレクトします。

使用するツールとスタック

ツール 目的 コスト(2026)
Screaming Frog デスクトップクローリング $259/年
Lumar (Deepcrawl) 大規模サイト用クラウドクローリング カスタム価格
Ahrefs バックリンク分析、ランク追跡 $129/月から
Google Search Console インデックス監視、クロール統計 無料
Redirectchecker.com 一括リダイレクトテスト 無料ティア利用可
ContentKing リアルタイムSEO監視 $99/月から
カスタムPython/Nodeスクリプト リダイレクトマッピング、コンテンツ差分 あなたの時間

実際のサイトビルドについては、プロジェクトのニーズに応じてNext.jsまたはAstroを使用し、Sanity、Contentful、またはStoryblokなどのヘッドレスCMSと組み合わせます。移行を計画していて、アーキテクチャについて話し合いたい場合は、当社の料金表を確認するかお問い合わせください

よくある質問

30,000ページのウェブサイトを移行するにはどのくらいの時間がかかりますか? 合計12〜20週間を予定してください。計画とURLマッピングフェーズが最も時間がかかります。通常8〜14週間かかります。実際の技術的移行とローンチは通常4〜6週間です。計画フェーズを急いでいることは、移行失敗の最大の予測因子です。

移行中にSEOトラフィックを確実に失いますか? 5-15%の一時的な低下は正常であり、完璧な移行でも予想されます。Googleは数万のリダイレクトを処理し、新しいサイトを再クロールするのに時間が必要です。低下は通常2〜3週間以内に解決します。より大きい低下が見られたり、回復しない場合は、リダイレクトと技術実装をすぐに調査してください。

移行中にURL構造を変更すべきですか? そうする強い理由がない限り、そうしないでください。すべてのURL変更はリスクを増加させます。現在のURL構造が機能的で説明的である場合は、それを保持します。それが本当に悪い場合(クエリパラメータを持つURLではなく、きれいなパスの代わりに)、移行は良い修正の機会です。ただし、リダイレクトマップに応じて計画してください。

サイトを段階的に移行して、一度にすべても大丈夫ですか? はい、非常に大規模なサイトではセクションごとに移行する方がしばしば安全です。最初にブログを、次に製品ページを、次にカテゴリページを移行できます。これはリスクを軽減しますが、通常リバースプロキシの背後で2つのプラットフォームを実行しているため、複雑さが増加します。複雑さが増加します。複数回これを成功裏に行いましたが、慎重なルーティング設定が必要です。

移行中にGoogle広告はどうなりますか? 移行の前後に広告ランディングページURLを新しいURLに更新します。リダイレクトがある場合、広告は引き続き機能しますが、リダイレクトはレイテンシを追加し、Google広告品質スコアは悪影響を受ける可能性があります。URLを直接更新する方が常に良いです。

移行中に削除したいページはどう処理しますか? ページにオーガニックトラフィックまたはバックリンクがあった場合、新しいサイトで最も関連するページにリダイレクトしてください。どちらも持っていなかった場合、404または410(Gone)ステータスを返すことができます。無関連のページをホームページにリダイレクトしないでください。Googleは大量のホームページリダイレクトをソフト404として扱います。

301または308リダイレクトを使用すべきですか? ほとんどの場合は301を使用します。どちらも永続的なリダイレクトですが、301はすべてのボット とブラウザで普遍的に理解されています。308はHTTPメソッドを保持します(POSTはPOSTのまま)。これはAPIエンドポイントには重要ですが、SEO重視のページリダイレクトではそうではありません。

古いリダイレクトをいつ削除するべきですか? 少なくとも1年間、できれば無期限に保持します。リダイレクトは維持するのが安いので、古いブックマーク、外部リンク、またはキャッシュされた検索結果が404を削除すると、削除を削除しながら削除する理由がほぼありません。