2026年10月8日

2026年10月8日

WordPressをHeadless CMSとして活用する方法:向き不向きの判断とWordPress側の準備

WordPress をヘッドレス CMS として使うと、記事の管理画面は WordPress のまま、表示を Next.js や Nuxt、Astro などの別のフロントエンドに任せられます。ただし、テーマやプラグインが担っていた表示まわりの機能を自分で作り直すことになるため、向いているサイトは限られます。この記事では、ヘッドレス化するかどうかの判断材料と、REST API か GraphQL かの選び方、WordPress 側で済ませておく準備(API の整備、認証、公開側の閉じ方、更新通知)を説明します。特定のフロントエンドでの実装手順は別記事に分け、ここでは CMS 側の設計に絞ります。

ヘッドレスCMSとは何が変わるのか

通常の WordPress は、記事データの保存と HTML の生成を1つのアプリケーションで行います。ヘッドレス構成では、WordPress は「データを保存して API で返す役」だけを担い、HTML の生成は別のアプリケーションが行います。

この分離で得られるものと失うものを並べると、判断がしやすくなります。

得られるもの

  • 表示側を React や Vue などで自由に作れる。アプリやデジタルサイネージなど、Web 以外にも同じ記事を配信できる。
  • 静的生成や CDN 配信と組み合わせると、表示の速さを保ちやすい。
  • 表示側のサーバーから WordPress を切り離せるため、管理画面を公開ネットワークから隠す構成も取れる。

失うもの・増える手間

  • テーマ、ウィジェット、ショートコード、フォームや SEO プラグインの表示部分は、そのままでは表示側に反映されません。必要なものは API 経由で取り出すか作り直します。
  • 下書きのプレビューが標準のままでは動きません。
  • WordPress と表示側の2つを運用・監視することになり、障害の切り分けも2か所になります。

更新担当者が少なく、テーマとプラグインで要件を満たせているサイトなら、ヘッドレス化しないほうが運用は楽です。「既存のフロントエンド開発チームがいる」「複数のチャネルに配信したい」「表示側を独自に作り込む理由がある」といった条件がそろったときに検討する価値があります。

REST APIかGraphQLか

WordPress には REST API が標準で組み込まれており、https://example.com/wp-json/wp/v2/posts のような URL で公開済みの投稿を JSON で取得できます。

GraphQL を使いたい場合は、WPGraphQL プラグインを入れると /graphql のエンドポイントが追加されます。WordPress.org のプラグインディレクトリで配布されています(2026年10月現在)。

観点 REST API(標準) WPGraphQL
導入 追加作業なし プラグインの追加が必要
取得の粒度 エンドポイント単位。_fields で項目を絞れる 必要な項目だけを1回の問い合わせで指定
関連データ _embed でアイキャッチや投稿者を同梱 クエリの中で関連をたどれる
キャッシュ URL 単位なので CDN と相性がよい POST が中心で、キャッシュには工夫が要る

小〜中規模のサイトや、取得するデータの形が単純な場合は REST API で十分なことが多いです。ページごとに多くの関連データをまとめて取りたい、型定義をフロントエンドで生成したいといった場合は WPGraphQL が便利です。ACF のフィールドを GraphQL で扱うには、別途連携用のプラグインが必要になる点も考慮してください。

REST API で応答を軽くするには、必要な項目だけを指定します。

/wp-json/wp/v2/posts?per_page=10&_fields=id,slug,title,excerpt,date

WordPress側の準備1:APIで取り出せる形にする

カスタム投稿タイプは、登録時に show_in_rest を true にしないと REST API に出てきません。カスタムフィールドも同様で、register_post_meta() で明示的に公開します。

add_action( 'init', function () {
	register_post_type(
		'case_study',
		array(
			'label'        => '導入事例',
			'public'       => true,
			'show_in_rest' => true,
			'rest_base'    => 'case-studies',
			'supports'     => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ),
		)
	);

	register_post_meta(
		'case_study',
		'client_industry',
		array(
			'type'              => 'string',
			'single'            => true,
			'show_in_rest'      => true,
			'sanitize_callback' => 'sanitize_text_field',
			'auth_callback'     => function () {
				return current_user_can( 'edit_posts' );
			},
		)
	);
} );

auth_callback は編集時の権限を判定するもので、公開範囲を決めるものではありません。show_in_rest を有効にしたフィールドは、公開された投稿であれば誰でも読めます。社内向けのメモなど、外に出したくない値は公開しないでください。

このコードはテーマを替えても動くよう、プラグインか mu-plugin に置くのが適しています。ヘッドレス構成では表示用のテーマを使わないため、functions.php に機能を書く理由も薄くなります。

WordPress側の準備2:認証の考え方

公開済みの記事を読むだけなら認証は要りません。認証が必要になるのは、下書きのプレビュー、会員限定コンテンツの取得、表示側からの投稿などです。

サーバー間の通信には、WordPress 5.6 で標準搭載されたアプリケーションパスワードが使えます。ユーザーのプロフィール画面で発行し、表示側のサーバーの環境変数に保存して、Basic 認証のヘッダーで送ります。

守るべき点は次のとおりです。

  • アプリケーションパスワードは表示側のサーバー内だけで使い、ブラウザに配信される JavaScript には含めない。
  • 専用のユーザーを作り、必要最小限の権限グループにする。管理者アカウントのパスワードを流用しない。
  • 通信は HTTPS に限る。アプリケーションパスワードは HTTPS でない環境では標準で使えないようになっています。
  • 漏えいが疑われたらプロフィール画面から個別に失効させる。

WordPress側の準備3:公開側のテーマ表示を閉じる

ヘッドレス化した後も、WordPress 本体の URL にアクセスすると古いテーマの画面が表示されます。同じ内容が2つの URL で公開されると、検索エンジンにとっても読者にとっても紛らわしいため、表示側へ転送するのが一般的です。

add_action( 'template_redirect', function () {
	if ( is_admin() || wp_doing_ajax() || is_preview() ) {
		return;
	}
	$front = 'https://www.example.com'; // 表示側のURLに置き換える
	$uri   = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '/';
	$path  = wp_parse_url( $uri, PHP_URL_PATH );
	wp_redirect( $front . ( $path ? $path : '/' ), 302 ); // 確認が済んだら301へ
	exit;
} );

REST API(/wp-json/)や管理画面、ログイン画面は template_redirect を通らないため、この転送の影響を受けません。転送先が外部ドメインなので wp_safe_redirect() ではなく wp_redirect() を使っていますが、転送先のドメインは固定値にし、リクエストから受け取るのはパス部分だけにしてください。WordPress をサブディレクトリに設置している場合は、パスの先頭からディレクトリ名を取り除く調整が要ります。最初は 302 で試し、表示側の URL 構造と一致することを確認してから 301 にすると、誤設定の影響を小さくできます。

WordPress側の準備4:更新を表示側に知らせる

静的生成やキャッシュを使う表示側では、記事を更新しても再生成されるまで反映されません。WordPress から表示側へ「更新があった」と知らせる仕組み(Webhook)を用意します。投稿の保存が完了した後に動く wp_after_insert_post フック(WordPress 5.6 以降)を使うと、タームやメタの保存も済んだ状態で通知できます。具体的な受け口の作り方は、フロントエンドのフレームワークごとに異なります。

通知には共有の秘密値を付け、表示側で照合してください。秘密値は wp-config.php の定数や環境変数に置き、コードやリポジトリに直接書かないようにします。

運用で気をつけること

  • SEO 情報:SEO プラグインの中には、REST API の応答にメタ情報を含めるものがあります。対応状況はプラグインのバージョンで変わるため、使っているプラグインのドキュメントで確認し、表示側で <title> や canonical を出力します。
  • ユーザー情報の露出:REST API の /wp/v2/users は、記事を公開している投稿者の情報を返します。不要なら表示名を実名にしない、エンドポイントを制限するなどの対策を検討します。
  • バックアップと更新:表示側に移しても WordPress 本体の更新、プラグインの脆弱性対応、バックアップは引き続き必要です。構成変更はステージング環境で試してから本番に反映してください。

まとめ

  • ヘッドレス化は表示の自由度と引き換えに、プレビュー・SEO・フォームなどを作り直す手間が増える。要件と体制を見て判断する。
  • 単純な構成なら標準の REST API、関連データをまとめて取りたいなら WPGraphQL。
  • カスタム投稿タイプは show_in_rest、カスタムフィールドは register_post_meta() で明示的に公開し、出したくない値は公開しない。
  • 認証はアプリケーションパスワードを表示側サーバー内だけで使い、専用ユーザーと最小権限で運用する。
  • 旧テーマの画面は表示側へ転送し、更新は秘密値付きの Webhook で表示側に知らせる。

お気軽にご相談ください

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