2026年5月30日

2026年5月30日

WordPressとGhostの移行・連携方法|双方向の移行手順と301リダイレクト、併用の構成

WordPressからGhostへ移るなら、Ghostが公開しているWordPress用の書き出しプラグインで移行ファイルを作り、Ghostの管理画面で読み込むのが基本の流れです。逆にGhostからWordPressへ移る場合は、Ghostの書き出しJSONをWordPressの投稿に変換して取り込みます。どちらの方向でも、URLの対応表を作って301リダイレクトを設定し、画像のURLを置き換えるところまでが移行作業です。この記事では、双方向の移行手順、リダイレクトと画像の扱い、移行せずに両方を使い分ける構成を説明します。

移行の前に決めておくこと

作業を始める前に、次の点を整理しておくと手戻りが減ります。

  • 移行か併用か:サイトをまるごと移すのか、ニュースレターや会員機能だけGhostを使い、サイト本体はWordPressのまま残すのか。併用なら記事の移行は不要な場合があります。
  • 移行する範囲:投稿、固定ページ、タグ、著者、画像は移行の対象になりますが、コメント、問い合わせフォーム、プラグイン独自のデータ(ショートコードやページビルダーの設定など)は、そのままでは移りません。
  • 購読者・会員:メールの購読者や会員は、記事とは別にCSVなどで移します。配信停止済みの人や同意の経緯が確認できない人は含めないようにします。

GhostとWordPressでは仕組みに違いがあります。Ghostには「カテゴリー」がなくタグで分類するため、WordPressのカテゴリーは移行時にタグとして扱われます。また、WordPressのショートコードやプラグイン固有のブロックはGhostでは解釈されず、文字列のまま残ったり表示が崩れたりします。移行後に手直しが必要な記事を洗い出すつもりで進めてください。

作業の前に、移行元のサイトのファイルとデータベースのバックアップを取っておきます。

WordPressからGhostへ移行する手順

1. 公式の書き出しプラグインで移行ファイルを作る

WordPressの管理画面で「プラグイン」→「新規追加」を開き、「Ghost」で検索して、Ghostが提供している書き出し用のプラグインをインストールします。作者がGhostであることを確かめてください。有効化すると「ツール」メニューに書き出し用の画面が追加され、そこからGhostで読み込める形式のファイルをダウンロードできます(2026年10月現在)。

記事や画像が多いサイトでは、書き出しの途中でタイムアウトやメモリ不足になることがあります。その場合は、画像を含めずに記事データだけを書き出す選択肢を使うか、Ghostが公開しているコマンドラインの移行ツール(@tryghost/migrate)を使う方法があります。移行ツールの使い方はGhostの公式ドキュメントで確認してください。

2. Ghostの管理画面で読み込む

Ghostの管理画面の設定にある、移行・インポート用の画面から、書き出したファイルをアップロードします。画面の名称や場所はGhostのバージョンによって異なるため、見つからない場合はGhostのヘルプで「WordPress」からの移行手順を検索してください。

本番のGhostに読み込む前に、可能であればテスト用のGhostで一度試します。同じファイルを2回読み込むと記事が重複することがあるため、やり直す場合は読み込んだ記事を削除してから行います。

3. 読み込み後に確認すること

  • 投稿と固定ページの件数が、WordPress側の公開数と合っているか
  • 公開日、スラッグ、タグ、著者の割り当てが正しいか
  • 下書きや予約投稿の扱いが想定どおりか
  • 画像が表示されるか。旧WordPressのドメインの画像URLが本文に残っていないか
  • ショートコードや埋め込み(YouTube、SNSの投稿など)が崩れていないか

旧サーバーの画像を直接参照しているURLが残っていると、旧サーバーを止めた時点で画像が表示されなくなります。旧ドメインで本文を検索し、残っている画像はGhostにアップロードし直してください。

GhostからWordPressへ移行する手順

1. GhostのコンテンツをJSONで書き出す

Ghostの管理画面の設定にある書き出し(Export)の機能で、記事やタグなどのデータをJSONファイルとしてダウンロードします。このJSONには画像ファイル自体は含まれません。セルフホストのGhostなら、サーバーのcontentディレクトリ内にあるimagesフォルダーを丸ごとコピーします。Ghost(Pro)を使っている場合は、画像の取得方法を公式の案内で確認してください。

2. JSONをWordPressの投稿に変換して取り込む

WordPressの標準のインポーターはGhostのJSONを直接読み込めないため、変換が必要です。変換用のツールやプラグインを使う方法もありますが、作者と更新状況を確認してから使ってください。ここでは、WP-CLIを使って自分で取り込む例を紹介します。

前提として、Ghostのimagesフォルダーの中身を、WordPressの wp-content/uploads/ghost/ にコピーしておきます。GhostのJSONでは、本文中のサイトのURLが __GHOST_URL__ という文字列に置き換えられていることが多いため、画像のURLをコピー先のURLに書き換えています。

<?php
// 使い方: wp eval-file ghost-import.php ghost-export.json --user=管理者のユーザー名
if ( ! defined( 'WP_CLI' ) ) {
	exit;
}

$file = isset( $args[0] ) ? $args[0] : '';
if ( ! is_readable( $file ) ) {
	WP_CLI::error( 'GhostのJSONファイルを指定してください。' );
}

$json = json_decode( file_get_contents( $file ), true );
$data = isset( $json['db'][0]['data'] ) ? $json['db'][0]['data'] : null;
if ( ! $data ) {
	WP_CLI::error( 'Ghostの書き出しファイルとして読み込めませんでした。' );
}

// 画像URLの置き換え(images の中身を uploads/ghost/ にコピーした前提)
$uploads   = wp_get_upload_dir();
$image_old = '__GHOST_URL__/content/images/';
$image_new = $uploads['baseurl'] . '/ghost/';

// タグID => タグ名(# で始まるGhostの内部タグは除外)
$tags = array();
foreach ( (array) ( $data['tags'] ?? array() ) as $tag ) {
	if ( 0 !== strpos( $tag['name'], '#' ) ) {
		$tags[ $tag['id'] ] = $tag['name'];
	}
}
$post_tags = array();
foreach ( (array) ( $data['posts_tags'] ?? array() ) as $row ) {
	if ( isset( $tags[ $row['tag_id'] ] ) ) {
		$post_tags[ $row['post_id'] ][] = $tags[ $row['tag_id'] ];
	}
}

foreach ( (array) ( $data['posts'] ?? array() ) as $p ) {
	$is_page = ( isset( $p['type'] ) && 'page' === $p['type'] ) || ! empty( $p['page'] );
	$type    = $is_page ? 'page' : 'post';

	if ( get_page_by_path( $p['slug'], OBJECT, $type ) ) {
		WP_CLI::log( 'スキップ(同じスラッグが既にある): ' . $p['slug'] );
		continue;
	}

	// 公開済みだけ公開、それ以外(下書き・予約など)は下書きで取り込む
	$status   = ( 'published' === $p['status'] ) ? 'publish' : 'draft';
	$date_raw = ! empty( $p['published_at'] ) ? $p['published_at'] : $p['created_at'];
	$date_gmt = gmdate( 'Y-m-d H:i:s', strtotime( $date_raw ) );

	$id = wp_insert_post( array(
		'post_type'     => $type,
		'post_title'    => $p['title'],
		'post_name'     => $p['slug'],
		'post_content'  => str_replace( $image_old, $image_new, (string) $p['html'] ),
		'post_status'   => $status,
		'post_date_gmt' => $date_gmt,
		'post_date'     => get_date_from_gmt( $date_gmt ),
	), true );

	if ( is_wp_error( $id ) ) {
		WP_CLI::warning( $p['slug'] . ': ' . $id->get_error_message() );
		continue;
	}
	if ( 'post' === $type && ! empty( $post_tags[ $p['id'] ] ) ) {
		wp_set_post_tags( $id, $post_tags[ $p['id'] ] );
	}
	WP_CLI::log( '取り込み: ' . $p['slug'] );
}

実行は、本番ではなくステージング環境で、データベースのバックアップを取ってから行います。--user で管理者を指定しないと、本文中のiframe(動画の埋め込みなど)が保存時に取り除かれることがあります。GhostのJSONの構造はバージョンによって違う場合があるため、少数の記事で試して、タイトル・本文・日付・タグが正しく入るかを確認してから全件を取り込んでください。

この方法では、コピーした画像はWordPressのメディアライブラリには登録されません。メディアライブラリで管理したい場合は、WP-CLIの wp media import で取り込み、本文のURLを置き換える作業が別に必要です。また、Ghostのカード(ブックマークやギャラリーなど)は専用のクラス名付きのHTMLで出力されるため、テーマによっては見た目を整えるCSSを追加します。

URLの対応と301リダイレクト

移行で検索順位や外部からのリンクを失わないために、旧URLから新URLへの301リダイレクトを設定します。まず、旧サイトのURLの一覧と新サイトのURLを並べた対応表を作ります。

WordPressからGhostへ:Ghostの記事URLは標準で /スラッグ/ の形式です。WordPressで /2024/05/スラッグ/ のような日付入りのパーマリンクを使っていた場合や、カテゴリーのURL(/category/〜/)を使っていた場合は、Ghostの設定画面からアップロードできるリダイレクト用のファイル(YAML形式など)で転送ルールを指定します。例えば日付入りのURLをスラッグだけのURLに転送するなら、次のような書き方になります。

301:
  ^\/\d{4}\/\d{2}\/([a-z0-9-]+)\/?$: /$1/
  ^\/category\/([a-z0-9-]+)\/?$: /tag/$1/
302:

GhostからWordPressへ:WordPressの「設定」→「パーマリンク」で「投稿名」を選ぶと、記事のURLはGhostと同じ /スラッグ/ の形式になり、多くの記事はリダイレクトなしで同じURLを保てます。タグ(/tag/〜/)と著者(/author/〜/)もWordPressの標準と同じ形式です。RSSのURL(Ghostの /rss/)はWordPressでは /feed/ になるため、ここは転送を設定します。リダイレクトはRedirectionなどのプラグインか、サーバーの設定で行います。

ドメインも変わる場合は、旧ドメインのサーバーをすぐに止めず、リダイレクトを設定したまましばらく維持します。移行後は、Search Consoleでサイトマップを送り直し、404エラーになっているURLがないかを確認してください。

移行せずにGhostとWordPressを併用する

サイトはWordPressのままにして、ニュースレターの配信や有料会員の機能だけをGhostで運用する構成もあります。例えば example.com をWordPress、news.example.com をGhostにする形です。

  • 登録フォーム:Ghostには、外部サイトに貼れる購読フォームを発行する機能があります。発行したコードをWordPressの「カスタムHTML」ブロックに貼ると、WordPressのページからGhostの購読者として登録できます。
  • 新着記事の表示:GhostのRSS(/rss/)を、WordPressの「RSS」ブロックで読み込むと、Ghostの新着記事をWordPress側に一覧表示できます。開発者であれば、GhostのContent APIを使って表示する方法もあります。
  • 重複に注意:同じ記事を両方に全文で載せると重複コンテンツになりやすいため、どちらを正規の掲載先にするかを決めておきます。

併用する場合も、プライバシーポリシーに外部サービスでメールアドレスを管理することを追記し、購読は確認メール(ダブルオプトイン)などで本人の意思を確認できる形にしておきます。配信停止の手段が届くメールに含まれているかも確認してください。

まとめ

  • WordPressからGhostへは、Ghost公式の書き出しプラグインで作ったファイルをGhostで読み込む。大きなサイトは移行ツールの利用も検討する
  • GhostからWordPressへは、書き出しJSONを変換して取り込む。画像はJSONに含まれないため別にコピーし、URLを置き換える
  • 移行後は件数、日付、タグ、画像、埋め込みを確認し、旧ドメインの画像URLが残っていないかを検索する
  • 旧URLと新URLの対応表を作り、301リダイレクトを設定する。Ghost→WordPressならパーマリンクを「投稿名」にするとURLを保ちやすい
  • 移行しない選択肢として、ニュースレターはGhost、サイトはWordPressという併用の構成もある

お気軽にご相談ください

お見積りへ お問い合わせへ
▲