開発

CMS移行の手順:WordPressの書き出しからURL対応表・301一括設定・移行後の計測まで

CMS移行の手順:WordPressの書き出しからURL対応表・301一括設定・移行後の計測まで

CMS移行でつまずく箇所は、記事データの移し替えよりもURLです。旧URLと新URLの対応表が無いまま切り替えると、検索流入と被リンクの評価が404で途切れます。この記事では、WordPressなどの既存CMSから別のCMSへ移すときの作業を、記事の書き出し、URL対応表の作成、301リダイレクトの一括設定、切り替え後の計測の順にコマンド付きで説明します。CMS移行の手順と注意点を、手を動かす担当者の目線でまとめました。

まとめ:CMS移行ではURL対応表を最初に作り、記事データの変換はその後に回す

作業の順番を一つだけ挙げるなら、URL対応表が先です。旧サイトの全URLを集め、新URLとの対応をCSVで確定させてから記事データを変換すると、移行漏れと404の両方を同じ表で潰せます。

記事の書き出しはWordPressならwp export(WXR形式)かREST APIのどちらかで足ります。301リダイレクトは件数で置き場所を決めます。数千件までならNginxのmap、ドメインごとCDNに載っているならCloudflareのBulk Redirectsが扱いやすい選択肢です。切り替え後は対応表の全URLへリクエストして転送先を検証し、Google Search Consoleで旧URLの404とクリック推移を数週間以上追います。

管理画面の使いにくさだけが動機なら、移行より既存CMSの改修が安く済む場合が多くあります。移行するかどうかの判断は、最後の本文章で条件を示します。

CMS移行で移す対象の棚卸しと、移行先の方式による作業量の違い

CMSの方式そのものの違いはCMSとは?仕組み・種類・WordPressとヘッドレスの違いで整理しています。ここでは移行作業に入る前に、何をどこへ移すかを決めます。

記事本文・画像・URL・計測タグ・フォームの5種類で移行対象を洗い出す

移行対象は記事本文だけではありません。漏れやすいのは画像ファイル、URL、計測タグ、問い合わせフォームの4つです。

  • 記事本文とメタ情報:タイトル、本文、公開日、更新日、カテゴリ、タグ、アイキャッチ、SEO用のtitleとmeta description
  • 画像などの添付ファイル:本文に埋め込まれた画像URLの書き換えも含む
  • URL:記事、カテゴリ一覧、タグ一覧、著者ページ、ページ送り、フィード
  • 計測タグ:Googleタグ、広告のコンバージョンタグ、ヒートマップ
  • フォームと外部連携:問い合わせフォーム、資料ダウンロード、CRMへの送信

SEO用のtitleとmeta descriptionはプラグインの独自フィールドに入っていることが多く、標準の書き出しに含まれるかをプラグインごとに確認します。フォームは移行先で作り直しになる前提で、送信先と自動返信の文面を先に控えておきます。

移行先がWordPress・ヘッドレスCMS・静的サイトの場合の作業量の比較

同じ「CMS移行」でも、移行先の方式で作業の重さが変わります。

移行先 記事データ URL 主な追加作業
別サーバーのWordPress WXRをそのまま取り込み 維持しやすい サーバー設定とDNS切り替え
ヘッドレスCMS コンテンツモデルへ変換 フロント側で再設計 フロントエンド開発と301
静的サイト+Git Markdownなどへ変換 生成器の規則に従う ビルドと配信の構築、301

同じWordPressのままサーバーだけ移す作業は、WordPress移行(サーバー引っ越し)の手順と注意点で扱っています。Wixなど他サービスからWordPressへ乗り換える場合は他サービスからWordPressへの移行が近い手順です。この記事が中心に扱うのは、表の2行目と3行目、つまりデータ構造もURL規則も変わる移行です。

WordPressから記事データを書き出す手順:WXRとREST APIの使い分け

WordPressからの書き出しには2つの経路があります。移行先がWordPressならWXR、それ以外ならREST APIのJSONが変換しやすい形です。

wp exportでWXRを書き出すコマンドと15MB分割・投稿タイプ指定

WP-CLIのwp exportは、作成者・カテゴリやタグなどのターム・投稿・コメント・添付ファイルの情報をWXR(WordPress eXtended RSS)形式のXMLに書き出します。サイト設定と添付ファイルの実体は含まれません。画像は別途コピーが必要です。

# 投稿と固定ページだけを、exportディレクトリへ書き出す
wp export --dir=./export --post_type=post,page --max_file_size=50

# 2024年以降に公開した記事だけを試しに書き出す(変換スクリプトの確認用)
wp export --dir=./export --post_type=post --start_date=2024-01-01 --max_num_posts=20

# 画像の実体は wp-content/uploads をそのまま複製する
rsync -av user@old-server:/var/www/html/wp-content/uploads/ ./export/uploads/

--max_file_sizeの既定は15MBで、超えると複数ファイルに分割されます。分割されたファイルは取り込み側で順に読む必要があるため、変換スクリプトを書く場合は上限を上げて1ファイルにまとめると扱いが楽になります。

REST APIのper_page上限100件とX-WP-TotalPagesで全件取得

ヘッドレスCMSや静的サイトへ移す場合は、REST APIのJSONを起点にした方が変換処理を書きやすくなります。Posts エンドポイントのper_pageは既定10件で、Paginationの仕様では1〜100の範囲です。総ページ数はレスポンスヘッダのX-WP-TotalPagesで分かります。

import csv, json, urllib.request

BASE = "https://old.example.com/wp-json/wp/v2/posts"
FIELDS = "id,slug,link,date,modified,categories,tags,featured_media"

rows, page = [], 1
while True:
    url = f"{BASE}?per_page=100&page={page}&_fields={FIELDS}"
    with urllib.request.urlopen(url) as res:
        total_pages = int(res.headers["X-WP-TotalPages"])
        rows += json.load(res)
    if page >= total_pages:
        break
    page += 1

with open("old_posts.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.DictWriter(f, fieldnames=FIELDS.split(","))
    w.writeheader()
    w.writerows(rows)
print(len(rows), "件を書き出しました")

_fieldsパラメータで必要な項目だけに絞ると、本文を含まない一覧を短時間で取れます。この一覧は次章の対応表の材料になります。本文が必要なときはcontentを足してください。statusの既定はpublishなので、下書きや予約投稿は認証を付けたリクエストでないと取得できません。

ショートコード・独自フィールド・本文中の画像URLの変換で詰まる箇所

変換で手が止まるのは、本文に埋め込まれたWordPress固有の記法です。などのショートコードは、REST APIの表示用本文では展開済みのHTMLになりますが、WXRでは記法のまま残ります。移行先にショートコードの仕組みは無いため、どちらの本文を正とするかを最初に決めます。

カスタムフィールドとSEOプラグインの値は、プラグインがREST APIに公開していなければJSONに出てきません。この場合はWXRのwp:postmetaから拾うか、データベースから直接読みます。本文中の画像URLは旧ドメインのwp-content/uploadsを指したままなので、新しい配信先のパスへ一括置換する処理を変換スクリプトに含めます。

旧URLと新URLの対応表をCSVで作る手順と、抜け漏れの検出方法

対応表は移行作業全体の台帳です。旧URLの一覧、新URL、転送の要否、確認結果を1つのCSVで管理します。

サイトマップ・アクセス解析・Google Search Consoleで旧URL全件収集

Google検索セントラルのサイトを移転する方法では、旧URLの一覧をサイトマップ、サーバーログ、アクセス解析ツール、CMS、Google Search Consoleなどから作るよう案内しています。CMSが把握しているURLだけでは足りません。過去に削除した記事や、パラメータ付きで被リンクを受けているURLは、ログとGoogle Search Consoleにしか残っていないからです。

実務では、前章のREST APIの一覧に、Google Search Consoleの「ページ」レポートの書き出しと直近1年のアクセスログに出たURLを足し、重複を除いて旧URL一覧とします。画像やPDFのURLも被リンクを受けていれば対象に含めます。

slugを軸に旧URLと新URLを突き合わせるCSVの列設計と照合

対応表の列はold_path、new_path、status(301か410か)、checkedの4つで足ります。記事のslugを移行先でも維持できれば、旧URLのパスから新URLを機械的に組み立てられます。

import csv
from urllib.parse import urlparse

# 旧: /2019/05/cms-guide/  新: /blog/cms-guide/  の規則で組み立てる例
with open("old_posts.csv", encoding="utf-8") as src, \
     open("url_map.csv", "w", newline="", encoding="utf-8") as dst:
    w = csv.writer(dst)
    w.writerow(["old_path", "new_path", "status", "checked"])
    for row in csv.DictReader(src):
        old_path = urlparse(row["link"]).path
        w.writerow([old_path, f"/blog/{row['slug']}/", "301", ""])

規則で組み立てられないURLが残ります。カテゴリ一覧、タグ一覧、著者ページ、統合や削除をする記事です。これらは手で転送先を決め、対応する記事が無いものはstatusを410にします。対応表の行数が旧URL一覧の件数と一致していることを最後に数えて確認します。

301リダイレクトを一括設定する置き場所の選び方とNginx mapの設定例

301と302、307、308の違いはリダイレクトとは?301・302・307・308の違いで説明しています。Googleが恒久的な移転に勧めているのは、サーバーサイドの301か308です。ここでは数百〜数万件の転送をどこに置くかを決めます。

Nginxのmapとincludeで数千件の301を1ファイルにまとめる設定例

Webサーバーを自分で管理しているなら、Nginxのmapモジュールが扱いやすい方法です。mapは外部ファイルをincludeで読み込めるため、対応表CSVから生成した1ファイルで転送を管理できます。mapはhttpコンテキストに書きます。

# /etc/nginx/conf.d/cms_redirect.conf(http コンテキスト)
map $uri $cms_new_path {
    default "";
    include /etc/nginx/redirects.map;
}

server {
    listen 443 ssl;
    server_name www.example.com;

    if ($cms_new_path) {
        return 301 $cms_new_path;
    }
}

# /etc/nginx/redirects.map(url_map.csv から生成)
/2019/05/cms-guide/    /blog/cms-guide/;
/category/news/        /news/;

$uriはcoreモジュールの説明のとおり、%XXをデコードした後の正規化されたURIです。日本語slugの記事では、対応表のパーセントエンコードされたパスをデコードしてから書く必要があるため、記載時に確認してください。件数が増えて起動時にハッシュの拡大を求められたら、nginxのハッシュ設定の説明に従い、先にmap_hash_max_size(既定2048)を上げます。設定を変えたらnginx -tで構文を確かめてから再読み込みします。

Cloudflare Bulk Redirectsのプラン別上限と正規表現を使えない制約

サイトをCloudflareに載せているなら、Bulk RedirectsでWebサーバーに触らず転送を置けます。Redirectsの提供範囲では、リストに登録できるURLリダイレクトの合計がFreeで10,000件、Proで25,000件、Businessで50,000件、Enterpriseで1,000,000件(既定の上限)です。

制約は、Bulk Redirectsが静的な1対1の対応表で、文字列置換や正規表現を使えない点です。「/2019/05/以下をまとめて/blog/へ」のような規則による転送はSingle Redirectsの領分で、ルール数はFreeで10、Proで25に限られます。Bulk RedirectsはWAFの後に実行されるため、WAFのルールで止められたリクエストは転送されません。旧URLへのアクセスをWAFで弾いていないかも確認します。

トップページへの一括転送と、多段の転送を作らないための判断基準

対応する記事が無い旧URLを、まとめてトップページへ転送するのは避けます。Googleの移転ガイドでも、多数の旧URLを無関係な1ページへ転送しないよう注意を促す記述がありますので、転送先を確認してください。内容の対応しない転送はソフト404として扱われる可能性があり、転送しない410の方が状態を正しく伝えられます。

もう一つの落とし穴は、過去のリダイレクトとの重なりです。旧サイトにすでに「A→B」の転送があり、今回「B→C」を足すと、Aは2段の転送になります。対応表を作るときには既存の転送設定も読み込み、Aの転送先をCへ直接書き換える作業が必要です。多段の転送がどこまで許されるかはリダイレクトチェーンとは?Googleは10ホップまで・推奨3個以下の根拠で扱っています。

切り替え当日から移行後の計測:転送の検証・404の監視・流入の比較

切り替え後の確認は、当日の全件検証と、数週間以上の推移の監視に分かれます。

切り替え直後に対応表の全URLへリクエストして転送先と応答コードを検証

DNSやWebサーバーを切り替えたら、対応表の全行について、旧URLへのリクエストが1回の301でnew_pathに着くかを確かめます。リダイレクトを追わずに1段目のLocationを見るのが要点です。追ってしまうと多段の転送を見逃します。

#!/usr/bin/env bash
# url_map.csv の全行を検証し、結果を verify.csv に書く
SITE="https://www.example.com"
tail -n +2 url_map.csv | while IFS=, read -r old new status checked; do
  result=$(curl -s -o /dev/null -w "%{http_code},%{redirect_url}" "$SITE$old")
  code=${result%%,*}
  location=${result#*,}
  if [ "$code" = "$status" ] && [ "$location" = "$SITE$new" ]; then
    echo "$old,$new,OK" >> verify.csv
  else
    echo "$old,$new,NG,$code,$location" >> verify.csv
  fi
done
grep -c ",NG," verify.csv

410の行はlocationが空になるので、比較を応答コードだけにする分岐を足してください。NGの件数が0になってから、転送先の新URLが200を返すかも同じ要領で全件確かめます。

Google Search Consoleへサイトマップ送信・アドレス変更ツールの条件

新サイトのサイトマップをGoogle Search Consoleに送信します。Googleの移転ガイドは、旧サイトマップも残して旧URLのインデックス数が減っていく様子を監視する方法を示しています。

アドレス変更ツールを使うのは、ドメインかサブドメインが変わる場合だけです。同じドメインの中でパスが変わるだけのCMS移行や、wwwの有無、HTTPからHTTPSへの変更には使いません。ドメインごと変える場合は、旧ドメインの確認済みプロパティから新ドメインへ申請します。

流入の比較は数週間以上かかる前提で、旧URL別の404とクリックを追う

Googleは、中規模サイトの移転で検索結果が落ち着くまでに数週間以上かかることがあり、大規模サイトではさらに長いと説明しています。切り替え翌週に流入が下がっても、すぐに設定を戻す判断はしません。

毎週見るのは2つです。1つはGoogle Search Consoleの「ページ」レポートで、見つからない(404)に旧URLが新たに出ていないか。もう1つは、移行前にクリックの多かった上位の記事について、新URLのクリックが旧URLの水準へ戻っているかです。404に出た旧URLは対応表に行を足して転送を追加します。リダイレクトは一般に少なくとも1年は維持するよう案内されているため、旧サーバーやCDNの設定を早く消さないよう運用担当に引き継ぎます。

CMS移行を社内で進めてよい条件と、移行そのものを見送るべき場面

ここまでの作業量を踏まえ、移行をどう進めるかの判断を条件付きで示します。

URLを維持でき独自フィールドが少ない記事のCMS移行は社内で回せる

旧サイトのslugとURL規則を移行先でそのまま再現でき、記事にカスタムフィールドやショートコードがほとんど無いなら、社内のエンジニアで十分に回せます。この条件では転送が少数で済み、前述のREST APIの一覧から記事を変換すれば作業の大半が終わります。

逆に、URL規則の変更、カテゴリ体系の作り直し、記事の統合が同時に起きるなら、対応表の手作業部分が一気に増えます。この組み合わせを自社だけで抱えると、転送の抜けが公開後に404として出てきます。

管理画面の不満だけが動機なら、移行せず既存CMSの改修で止める

「編集画面が使いにくい」「プラグインの更新が怖い」という理由だけで移行を決めるのは過剰です。この場合は移行しません。WordPressなら、ブロックパターンや入力項目の整理、不要なプラグインの削除で解消できる不満がほとんどだからです。

移行に踏み切るのは、記事を複数のサイトやアプリへ配信したい、表示速度の要件を既存の構成では満たせない、といった構造上の理由があるときに限ります。ヘッドレスCMSへ移す価値があるかはヘッドレスCMSとは?従来型との違い・料金比較とプレビュー実装、移行先の候補の比べ方はCMS選定の進め方と選び方で確認できます。

URL変更と構造の作り直しが重なる移行を外部に任せるときの依頼範囲

外部に依頼するときは、移行先CMSの構築だけでなく、旧URLの収集、対応表の作成、301の設定、切り替え後の全件検証までを依頼範囲に含めます。見積もりの段階で、旧URLの件数と、規則で転送を組み立てられない行の見込み件数を伝えると、作業量のずれを防げます。

一創では、WordPressとヘッドレスCMSの構築に加えて、既存サイトからの記事移行とURL設計を含めたWordPressサイト制作・CMS構築を受けています。サイト全体を作り直すかどうかの判断から始めたい場合は、サイトリニューアルの進め方|SEO評価を落とさない6ステップも参考になります。

よくある質問

CMS移行の作業でよく聞かれる質問をまとめました。

CMS移行にかかる期間の目安はどれくらいですか?

期間を決めるのは記事数よりも、規則で転送先を組み立てられないURLの数と、移行先のフロントエンドを作り直すかどうかです。同じWordPressへ移すだけなら、書き出しと取り込み、DNS切り替えで済みます。ヘッドレスCMSや静的サイトへ移す場合は、コンテンツモデルの設計とフロントエンド開発が加わり、対応表の作成と検証も並行して進めます。切り替え後も、検索流入が落ち着くまでの数週間以上は監視の期間として見込んでください。

CMS移行でURLは変えない方がよいですか?

変えずに済むなら変えない方が安全です。URLが変わらなければ転送が要らず、被リンクと検索評価の引き継ぎを心配する必要がありません。移行先のCMSや静的サイト生成器の多くは、URLの規則を設定で変えられます。WordPressの/年/月/slug/のような形を再現できるかどうかは、移行先を選ぶ段階での確認事項です。どうしても変える場合は、この記事の対応表と301の手順で全件を転送します。

WordPressの画像は移行先にどう移せばよいですか?

WXRには添付ファイルの情報が入りますが、画像ファイルの実体は入りません。wp-content/uploadsをフォルダごと複製し、移行先の配信場所へ置きます。本文中の画像URLは旧ドメインを指しているため、変換時には新しいパスへの置換も必要です。画像のURLも外部から直接リンクされていることがあるので、アクセスログに出ている画像URLは対応表に含めて転送します。

リダイレクトはいつまで残しておけばよいですか?

Googleのサイト移転ガイドは、リダイレクトを一般に少なくとも1年は維持し、できるだけ長く残すよう勧めています。被リンクは移行後も旧URLのまま残り続けるため、利用者の側から見れば期限を設けない運用も選択肢です。NginxのmapやCloudflare Bulk Redirectsなら転送を残し続けてもほぼ手間がかからないので、旧サーバーを廃止するときに設定を新しい環境へ持っていくことを忘れないようにします。

移行後に検索順位が下がったときは何を確認しますか?

最初に、旧URLが1回の301で正しい新URLへ着いているかを対応表の全件で確かめます。次にGoogle Search Consoleの「ページ」レポートで確認するのは、404やソフト404に旧URLが出ていないかという点です。転送が正しいのに順位が戻らない場合は、新URLのtitleや本文、内部リンクが旧ページから欠けていないかを比べます。移転後の数週間は変動が出やすいため、設定を戻す判断は急がないでください。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.11.03 テックブログ ノジマ不正アクセスで約700万件漏えい:対象確認・窓口と乗っ取り注文を止める実装
  2. 2026.10.29 テックブログ ソニー生命の情報漏洩38.5万件|ログインできない理由、再開状況と窓口の電話番号
  3. 2026.11.03 テックブログ クラブツーリズム不正アクセス:約432万件の対象確認と偽メールの見分け方・流出検知の設計
  4. 2026.11.04 テックブログ CVE-2026-119977:WordPress更新中のRCEと安全な更新手順
  5. 2026.11.02 テックブログ アララの不正アクセス:メール約7,700万件の持ち出しと契約企業が行うAPIキー再設定・代替送信・連名報告

RELATED POSTS 関連記事

目次