3年前、クライアントのブログを移行しました。400投稿、月間オーガニック訪問数6万、8年間蓄積されたPageRank。ピカピカのNext.jsフロントエンドに。6週間以内に、トラフィックの34%を失いました。新しいサイトが遅かったから?いいえ。コンテンツが消えたから?いいえ。私が4つの特定の点でずさんだったから。このポストで、その4つをあなたに説明します。あなたが同じ過ちを繰り返さないように。
Next.jsを使ったヘッドレスWordPressは、パフォーマンスとデベロッパー体験という点で本当に優れています。ですが、canonical タグが間違っていて、XMLサイトマップが古いドメインを指していて、構造化データがWPGraphQLとgetStaticPropsの間のどこかで消えてしまっていたら、Lighthouse スコアがいくら良くてもGoogleは気にしません。危険なのは、実はこの移行プロセス自体です。正しく実行するのに必要なのは、ほとんどの場合、魔法ではなく規律です。
---
最初にこの移行がSEOを壊してしまう理由
ほとんどのチュートリアルが触れない重要なポイントはこれです。WordPressは、あなたが気づかないうちに莫大なSEO上の重い仕事をあなたの代わりにやっているということです。YoastやRank Mathがメタタグを生成しています。WordPressコアがパーマリンク構造を処理しています。あなたのテーマはおそらく何らかのスキーママークアップを出力しています。XMLサイトマップは、あなたが公開するたびに自動的に再生成されます。
WPGraphQL APIを経由してNext.jsにコンテンツレイヤーを引き込んで、新しいフロントエンドから配信する場合、そのインフラのすべてがあなたが複製しなければならない問題になります。すべてです。本当にすべてです。
もう一つの問題がURL構造です。ほとんどのWordPressサイトは/category/post-slug/、または/year/month/post-slug/、あるいは単に/post-slug/といった構造を持っています。Next.jsはルーティングについて白紙の状態を提供します。その白紙の状態は、慎重に計画しなければランク低下の墓場になります。
私が常に目にしている2つの失敗パターン
1つ目は、URLも移行しながらそれでも何かを壊すチーム。たいていリダイレクトが一貫性なく適用されるか、新しいサイトマップがリダイレクトより前にライブになるから。2つ目は、意図的にURLの構造を変更するチーム(クリーンアップするためにたいてい)そしてリダイレクトマッピングを後付けの仕事として扱うこと。どちらも修正できます。どちらも許容できません。
---
何かに触れる前に監査を行う
Next.jsのコードを1行も書く前に、完全なURL在庫を用意してください。Screaming Frogを使って、ライブのWordPressサイトをクロール、すべてのインデックス対象URLをエクスポート、スプレッドシートに入れます。400ページサイトなら、たぶん1時間の作業です。4,000ページサイトでも、まだ1時間です。ツールが自動でやるから。
キャプチャしているもの:
- 現在インデックスされているすべての正規URL
- 各URLのHTTPステータス(既に存在する404と301を特定)
- すべてのページのメタタイトルと説明
- 構造化データを持つページ(Rich Results Testを使用するか、ソースを検査するだけ)
- インバウンド内部リンク。どのページがどのページにリンクしているか知る。
Google Search Consoleから上位50ページをクリック数でソートして取得します。これらは間違えられないページです。スプレッドシートにフラグを付けます。本番環境の依存関係のように扱ってください。
Seahawkは2022年後期にあるeコマースクライアントがいました――1,200商品のWooCommerceストアがヘッドレス化へ移行。コードを書く前に、2日間まるごと監査に費やしました。クライアントは時間の無駄だと思いました。月9万オーガニックセッションを救いました。
---
WordPressを真のヘッドレスCMSとして設定する
この部分は大部分が単純です。WPGraphQLをインストールしてGraphQL APIを通じてコンテンツを公開するだけです。ただし、意図的に検討する価値のある点がいくつかあります。
WordPress側でYoast(またはRank Math)を実行し続ける
もはやWordPressをパブリックフロントエンドとして配信していなくても、SEOプラグインはアクティブのままにしておいてください。WPGraphQL for Yoast SEO(またはそれに相当するRank Math拡張)は、すべてのSEOメタ、タイトル、説明、正規URL、OGデータ、ロボット指令をGraphQL APIを通じて直接公開します。つまり、Next.jsからクエリして、Yoastが意図した通りに正確にレンダリングできます。
これは、先ほど述べた2019年のトラフィック低下から得た教訓だ。Next.jsでポストタイトル + サイト名からタイトルを再生成できると考えていた。実際にできた。だが、Yoastが上位パフォーマンスのポストの約80個に対してメタタイトルを手動でカスタマイズしており、我々はそれをすべて削除してしまった。回復に8週間かかった。
WordPress フロントエンドを慎重に無効化する
Next.jsへのトラフィックをポイントする準備ができたら、WordPressが同時に自身のフロントエンドを配信していてはいけません。大規模な重複コンテンツになります。最もシンプルなやり方は、WordPressインストールのrobots.txtでDisallow: /を設定してNext.jsサイトを本番運用に移す、その後、eventually WordPressのURLをファイアウォールで完全に遮断してVPNまたは内部アクセスのみにすることです。
robots.txt のステップをスキップするな。CDNレベルでWordPressをブロックした後、Googlebot がキャッシュされたルートを持っていたことに気付くチームを見てきた。クリーンアップに数ヶ月かかる。
---
URL構造を完全に複製する
強い推奨デフォルト:URL を同じにしておく。同じスラッグ、同じパーマリンク構造、同じトレーリングスラッシュの動作。Next.js のルートが WordPress のルートをどれだけ正確にミラーリングするかが、必要なリダイレクト数と抱えるリスクを左右する。
Next.jsのダイナミックルートはこれを簡単にします。WordPressのポストが/blog/[slug]にあれば、pages/blog/[slug].jsを作成します。それで完了です。
複雑になるのはカテゴリーアーカイブ、著者ページ、タグページ、ページネーションアーカイブ(/blog/page/2/)だ。WordPress はこれらすべてを自動生成する。Next.js では自分でビルドしている。多くのチームはこれらを後回しにして、その後クロールカバレッジが低下した理由に首をかしげている。
ここが URL パリティのための番号付きチェックリストだ:
- 単一投稿/ページ。スラッグを正確に一致させてください。サブフォルダも含めて。
- カテゴリーアーカイブ。
/category/[slug]/を再作成。getStaticPathsでWPGraphQLからすべてのカテゴリーを取得。 - タグアーカイブ。上記と同じ。オーガニック流入を得ているなら、スキップしないこと。
- 著者アーカイブについては、まずSearch Consoleを確認してください。クリック数がゼロの場合は、ホームページへ301リダイレクトできます
- ページネーション付きアーカイブの
/blog/page/[num]/は、投稿が多い場合は保持する価値があります - 添付ファイルページは、ほぼ常に親投稿へ301リダイレクトしてください。WordPressでもSEO的な価値がありません
- フィードURL、
/feed/は新しいRSSフィードがあれば301リダイレクトするか、ない場合は410を返してください
---
リダイレクト — みんなが過小評価する部分
URLを変更する場合は、可能であれば避けるべきですが、時には必要です。その場合、リダイレクトマップをローンチ前に作成し、ステージング環境でテストしてください
Next.jsではリダイレクトはnext.config.jsに記述します。小規模サイト(200リダイレクト未満)ならそれでいいですが、それ以上の場合はJSONファイルに記述してインポートするか、ミドルウェアで動的に処理してください。Vercelのエッジミドルウェアは大規模なリダイレクトテーブルに最適です。ページがレンダリングされる前に実行され、レイテンシーのペナルティがゼロです
next.config.jsでのフォーマットは:
``redirects: [ { source: '/old-slug', destination: '/new-slug', permanent: true } ]``
permanent: trueは301を送信します。URL変更の場合は常に使用してください。302(一時的)は、実際に戻す予定がない限り使用しないでください。Googleはこれらを大きく異なる方法で扱います
本番環境にデプロイする前にすべてのリダイレクトをテストします。私はスプレッドシートをループして各古いURLをcurlで確認し、301レスポンスが正しい宛先に返されているかをチェックする簡単なbashスクリプトを使用します。作成に10分かかりますが、本番環境後のトラブル対応に何時間も浪費することを防ぎます。
---
Next.jsのメタタグ、Canonical URL、構造化データ
ここはほとんどのマイグレーションで静かに得点を失う場所です。コンテンツは存在し、URLは機能していますが、SEOシグナルが間違っています。
メタタグ
next-seoを使用してください。これが標準です。WPGraphQL Yoastから取得したデータを渡してください。your_app.jsはDefaultSeoの設定を取得し、各ページはページ固有のオーバーライドを含むNextSeoコンポーネントを取得します。タイトル、説明、OGタイトル、OG画像、正規URL、ロボット指令をYoast GraphQL応答から直接取得し、再度発明しないでください
ひとつ多くの人が引っかかるのはカノニカルURLだ。WordPressではYoastが自動的にカノニカルを設定する。Next.jsではカノニカルを明示的に渡す必要がある。忘れると、Next.jsはカノニカルタグなしでページをレンダリングし、ページネーションやフィルタなどでクエリ文字列があると、予想より早く重複コンテンツの問題に直面する。
構造化データ
WordPress テーマとプラグインはしばしば JSON-LD を自動的に出力します。ヘッドレスではそれは消えます。再構築する必要があります。記事の場合は Article スキーマを使用してください。製品の場合は Product を使用してください。ローカルビジネスの場合は LocalBusiness を使用してください。これらを props を受け取り <script type="application/ld+json"> タグを返す React コンポーネントとして記述します。スキーマタイプごとに 1 つのコンポーネント、アプリ全体で再利用します。
マイグレーション前に Rich Results Test で以前にあったすべてのスキーマタイプを確認してください。ドキュメント化してください。それらを再作成してください。同じツールで新しいスキーマを launch 後にテストしてください。
XMLサイトマップ
静的なサイトマップを使用しないでください。動的に生成してください。小規模サイトの場合、/sitemap.xmlルートでgetServerSidePropsを使用します。数千の投稿を持つ大規模サイトの場合、カスタムスクリプトを介してビルド時にサイトマップを生成し、public/フォルダに出力してください。Vercelはデプロイ時にこれを実行し、サイトマップは常に最新です
新しいサイトが本番環境で公開される初日に新しいサイトマップURLをGoogle Search Consoleに送信する。3日目ではなく。初日だ。
---
ローンチ後の監視(90日間のウィンドウ)
マイグレーションはローンチで終わりません。ランキングが安定するまで終わりません。Googleのドキュメントによると、クロール予算とサイト権限に応じて、数週間から数ヶ月かかる場合があります
毎営業日、最初の1ヶ月間でチェックすること:
- Google Search Console → Coverage レポートで新しい 404 または除外されるべきではない「Excluded」URL を確認してください。
- Search Console → Performance で、上位 50 ページのクリック数とインプレッション数を週単位で比較する
- 新しいサイトを Screaming Frog で再クロールして、内部 404 または誤って設定された canonical タグを検出してください。
- Core Web Vitals、そう、Next.js サイトは速くなるはずだが、Lighthouse だけでなくフィールドデータ(CrUX)で検証してほしい
最初の2〜3週間で大きなドロップが見られても、すぐにパニックにならないこと。Google が再クロールして再インデックスする中で、短期的な変動はほぼ必ず発生する。注視すべきは4週目を過ぎての持続的なドロップだ。それが何か構造的に問題があるというシグナルになる。
2022 年後半の話だが、e-commerce とは別のプロジェクトで、SaaS ブログの Next.js マイグレーションを実行し、2 週目にインプレッション数が 20% 低下した。原因は動的生成されたサイトマップが noindex ページを含んでいて、WPGraphQL クエリを正しくフィルタリングしていなかったからだ。4 時間で修正した。ランキングは 3 週間で回復した。監視によって問題が複合化する前に検出できた。
---
FAQ
WordPress から Next.js へのマイグレーションはどのくらい時間がかかる?
正直なところ、投稿数よりもサイトの複雑さに左右されます。クリーンなURLを持つ100ページのブロシュアサイトなら、2~3週間で適切に完成させられます。2,000個の投稿、カスタム投稿タイプ、ACFフィールド、WooCommerce統合を備えたブログなら、SEO作業を開発と並行して適切に行う場合、最低でも6~8週間のプロジェクト期間が必要です。誰かが週末の案件だと言っても信じないでください。
Next.jsではPages RouterかApp Routerどちらを使うべきですか?
2024 年中盤時点では、新規プロジェクトは App Router をデフォルトにしている。ただし、チームが Pages Router の方に慣れていて、このマイグレーションが時間的に逼迫しているなら、今知っていることを使ってもらっていい。SEO への影響は最小限だ。どちらも静的生成、サーバーサイドレンダリング、動的ルートをサポートしている。next-seo パッケージも今は App Router 対応している。
WordPressホスティングから完全に移行する必要がありますか?
いいえ。WordPress は既存のホストである WP Engine、Kinsta、Cloudways、どれを使っていようと、そのまま残してコンテンツ API として機能させるだけでいい。Next.js フロントエンドは Vercel か Netlify にデプロイする。この 2 つは HTTP で通信する。実際のところ、編集チームが既に知っている WordPress の管理画面を保ち続けられるため、これを好むクライアントも多い。
リダイレクト管理を行う Redirection のような SEO に影響を与える WordPress プラグインはどうするか
マイグレーション前にエクスポートしておく。Redirection プラグインは CSV エクスポート機能を持っている。既存のリダイレクトをすべて取り出して next.config.js か edge middleware に追加する。自動的に引き継がれるだろうと想定してはいけない。引き継がれない。なぜなら、それらは WordPress データベースに存在していて、Next.js はそれらの存在を知らないからだ。
どんなことをしてもGoogleのランキングは下がりますか?
ほぼ必ず短期的な変動がある。URL 変更がゼロで、適切なリダイレクト(必要な場合)、メタタグと構造化データの複製、サイトマップの再送信を伴う、よく実行されたマイグレーションなら、4~6 週間で安定する。数カ月続いたドロップは、すべてマイグレーション自体が原因ではなく、特定の技術的エラーが原因だった。
---
マイグレーション自体は難しくない。難しいのは、知識を要しない退屈な作業——監査、リダイレクトマッピング、スキーマの再作成——を、Next.js のコードを書く前にすべてやり遂げる規律だ。その順序を正しくすれば、より速いフロントエンドと、開始時と同じランキングを持って抜け出られる。場合によっては、Core Web Vitals の改善がランキングに反映されたあと、さらに良いランキングも期待できる。
