2026年5月28日
2026年5月28日
WordPressとCDP(顧客データプラットフォーム)を連携する方法
WordPress を Segment や RudderStack などの CDP(顧客データプラットフォーム)と連携するには、ブラウザ側で CDP 公式の JavaScript スニペットを読み込んで page・track・identify を送り、会員登録や注文完了のように取りこぼしたくない出来事はサーバー側のフックから送る、という2本立てが基本です。この記事では、事前に決めておくイベント設計、テーマへの組み込み方、WordPress と WooCommerce のフックからの送信、同意管理との組み合わせまでを説明します。
CDPとは何か、WordPressで何ができるか
CDP は、Web サイトやアプリ、決済システムなど複数の「ソース」から行動データを集め、ユーザー単位にまとめて、分析ツール・メール配信・広告・データウェアハウスなどの「デスティネーション」へ配る仕組みです。代表的な製品に Twilio の Segment や、オープンソース版もある RudderStack があります。
WordPress から見たときの利点は、計測タグを1つにまとめられることです。分析ツールや広告タグを個別に埋め込む代わりに CDP のスニペットだけを読み込み、どのツールにデータを流すかは CDP の管理画面で切り替えます。テーマにタグが増え続けるのを防げるほか、ツールを入れ替えるときにサイトのコードを触らずに済みます。
Segment と RudderStack は、どちらも次の呼び出しを中心にした共通の考え方を採っています。
- page: ページを表示したことを記録する
- track: 「資料請求フォームを送信した」など、名前の付いた行動を記録する
- identify: 匿名の訪問者とログインユーザーを結び付け、ユーザーIDと属性を記録する
先にイベント設計を決める
実装の前に、送るイベントの一覧(トラッキングプラン)を作っておきます。ここを曖昧にしたまま始めると、signup と Sign Up と 会員登録 が混在し、後で集計できなくなります。
| イベント名 | 送る場所 | 主なプロパティ |
|---|---|---|
| CTA Clicked | ブラウザ | label、location |
| Form Submitted | ブラウザ | form_id |
| Signed Up | サーバー(user_register) |
source |
| Order Completed | サーバー(WooCommerce) | order_id、total、currency |
決めておきたいのは、イベント名の書き方(例: 英語の「対象+過去形」)、プロパティ名、どちらの側から送るかの3点です。Segment には EC 向けの推奨イベント名が公開されているので、WooCommerce のサイトでは参考にすると後の連携が楽になります。
ブラウザ側: 公式スニペットを読み込む
CDP の管理画面で「JavaScript(Web)」の種類のソースを作ると、キー(Segment では Write Key)が発行され、そのキー入りの読み込みスニペットが表示されます。スニペットの内容は製品やバージョンで変わるため、記事などからコピーせず、自分のソースの画面から最新のものを取得してください(2026年10月現在)。
取得したスニペットは、テーマや自作プラグインの assets/js/cdp-snippet.js にそのまま保存します。ただし、同意を得てから読み込めるよう、全体を関数で包んでおきます。
// assets/js/cdp-snippet.js
window.myLoadCdp = function () {
if ( window.myCdpLoaded ) {
return;
}
window.myCdpLoaded = true;
// ここに CDP の管理画面からコピーしたスニペット本体を貼り付ける
// (<script> タグは除き、中身の JavaScript だけを貼る)
};
PHP 側では、このファイルと、イベントを送る自前のスクリプトを読み込みます。
add_action( 'wp_enqueue_scripts', function () {
// 管理画面のプレビューやステージングでは送らない
if ( 'production' !== wp_get_environment_type() ) {
return;
}
wp_enqueue_script( 'my-cdp-snippet', get_theme_file_uri( 'assets/js/cdp-snippet.js' ), array(), '1.0.0', false );
wp_enqueue_script( 'my-cdp-events', get_theme_file_uri( 'assets/js/cdp-events.js' ), array( 'my-cdp-snippet' ), '1.0.0', true );
$config = array( 'userId' => null );
if ( is_user_logged_in() ) {
// メールアドレスではなく、サイト内のIDを識別子にする
$config['userId'] = 'wp_' . get_current_user_id();
}
wp_add_inline_script( 'my-cdp-events', 'window.myCdpConfig = ' . wp_json_encode( $config ) . ';', 'before' );
} );
ログインユーザーのIDを HTML に出力するので、ログイン中のページがページキャッシュに保存されていないことを確認してください。多くのキャッシュプラグインはログインユーザーをキャッシュ対象外にしていますが、設定によっては例外があります。
track と identify を送る
ボタンやリンクのクリックは、HTML に data-cdp-event 属性を付けておき、まとめて拾うと管理が楽です。
<a href="/contact/" data-cdp-event="CTA Clicked" data-cdp-label="header-contact">お問い合わせ</a>
// assets/js/cdp-events.js
( function () {
var cfg = window.myCdpConfig || {};
function start() {
window.myLoadCdp();
var a = window.analytics; // Segment の場合。RudderStack では window.rudderanalytics
if ( ! a ) {
return;
}
// ログイン中なら identify、ログアウト後なら識別情報をリセット
if ( cfg.userId ) {
a.identify( cfg.userId );
localStorage.setItem( 'myCdpIdentified', '1' );
} else if ( localStorage.getItem( 'myCdpIdentified' ) ) {
a.reset();
localStorage.removeItem( 'myCdpIdentified' );
}
// data-cdp-event の付いた要素のクリック
document.addEventListener( 'click', function ( e ) {
var el = e.target.closest( '[data-cdp-event]' );
if ( el ) {
a.track( el.dataset.cdpEvent, {
label: el.dataset.cdpLabel || '',
location: window.location.pathname
} );
}
} );
// フォーム送信(入力内容は送らず、フォームの識別子だけ送る)
document.addEventListener( 'submit', function ( e ) {
var form = e.target;
if ( form.id ) {
a.track( 'Form Submitted', { form_id: form.id } );
}
} );
}
// 同意の仕組みから呼び出せるよう公開する。同意不要の地域・用途なら start() を直接呼ぶ
window.myCdpStart = start;
} )();
フォーム送信のイベントは、送信直後のページ遷移で届かないことがあります。問い合わせ件数のように正確さが要る数値は、完了ページの表示やサーバー側の処理で記録するほうが安定します。
page の送信は、多くの場合スニペットの末尾に含まれています。スニペットに page の呼び出しがあれば、自前のコードで重ねて送らないようにしてください。二重に送るとページビューが倍に数えられます。
identify に渡す属性(traits)には、メールアドレスや氏名を入れたくなりますが、メール配信ツールとの連携などで本当に必要な場合に限り、プライバシーポリシーで説明したうえで送ります。フォームの入力値をそのまま track のプロパティに入れるのも避けてください。
サーバー側: フックからイベントを送る
会員登録や注文完了は、広告ブロッカーやブラウザの終了でブラウザ側のイベントが欠けることがあります。重要な出来事は WordPress のフックからサーバー経由で送ると、取りこぼしを減らせます。CDP 側では「サーバー(HTTP API)」の種類のソースを別に作り、そのキーを使います。サーバー用のキーは公開しないため、wp-config.php に定数で置きます。
// wp-config.php
define( 'MY_CDP_ENDPOINT', 'https://your-cdp-endpoint.example.com/v1/track' ); // 利用する CDP のドキュメントで確認
define( 'MY_CDP_WRITE_KEY', 'your-server-write-key' );
送信処理は WP-Cron に回し、ユーザーの操作を待たせないようにします。WP-Cron はアクセスをきっかけに動くため、アクセスが少ないサイトでは送信が遅れます。気になる場合はサーバーの cron から wp cron event run --due-now を定期実行します。
function my_cdp_queue( string $event, string $user_id, array $properties ): void {
wp_schedule_single_event( time(), 'my_cdp_send', array( array(
'userId' => $user_id,
'event' => $event,
'properties' => $properties,
'timestamp' => gmdate( 'c' ),
'messageId' => wp_generate_uuid4(), // 再送時の重複判定に使う
) ) );
}
add_action( 'my_cdp_send', function ( array $payload ) {
if ( ! defined( 'MY_CDP_ENDPOINT' ) || ! defined( 'MY_CDP_WRITE_KEY' ) ) {
return;
}
$res = wp_remote_post( MY_CDP_ENDPOINT, array(
'timeout' => 10,
'headers' => array(
'Content-Type' => 'application/json',
'Authorization' => 'Basic ' . base64_encode( MY_CDP_WRITE_KEY . ':' ),
),
'body' => wp_json_encode( $payload ),
) );
if ( is_wp_error( $res ) || wp_remote_retrieve_response_code( $res ) >= 300 ) {
error_log( 'CDP send failed: ' . ( is_wp_error( $res ) ? $res->get_error_message() : wp_remote_retrieve_response_code( $res ) ) );
}
} );
// 会員登録
add_action( 'user_register', function ( $user_id ) {
my_cdp_queue( 'Signed Up', 'wp_' . $user_id, array( 'source' => is_admin() ? 'admin' : 'site' ) );
} );
// WooCommerce の注文完了(同じ注文で二重に送らない)
add_action( 'woocommerce_order_status_completed', function ( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order || $order->get_meta( '_my_cdp_sent' ) ) {
return;
}
my_cdp_queue( 'Order Completed', 'wp_' . $order->get_customer_id(), array(
'order_id' => (string) $order->get_id(),
'total' => (float) $order->get_total(),
'currency' => $order->get_currency(),
) );
$order->update_meta_data( '_my_cdp_sent', 1 );
$order->save();
} );
Basic 認証にキーを使う方式は Segment や RudderStack の HTTP API で採られていますが、エンドポイントの URL はデータの保存地域やプランによって異なります。利用中の CDP のドキュメントで URL と認証方式を確認してから設定してください。
注文の状態が「完了」になるのは、ストアの運用によっては発送後です。決済の時点で記録したい場合は、決済完了時に呼ばれるフック(woocommerce_payment_complete など)を使うかを検討します。ゲスト購入では get_customer_id() が 0 になるため、匿名IDの扱いも決めておきます。
同じ出来事をブラウザとサーバーの両方から送ると二重計上になります。トラッキングプランで「どちらから送るか」を決めたのはこのためです。
同意管理と組み合わせる
計測や広告目的のデータ送信には、地域や用途によって事前の同意が求められます。上のコードでは、スニペットの読み込みとイベント送信を window.myCdpStart() を呼ぶまで行わないようにしています。同意管理ツール(CMP)を使っている場合は、訪問者が計測に同意したときのコールバックや、同意状態が保存済みのページ表示時に myCdpStart() を呼びます。WordPress では、同意状態をプラグイン間で共有するための WP Consent API という仕組みもあり、対応した同意プラグインと組み合わせられます。
あわせて、プライバシーポリシーに CDP を利用していること、送っている情報の種類、データを渡す先のツールを記載します。どの規則が適用されるかは対象地域や事業内容で変わるため、判断に迷う場合は専門家に相談してください。
動作確認
CDP の管理画面には、ソースに届いたイベントをほぼリアルタイムで表示するデバッグ用の画面があります。次の順で確認すると、問題の切り分けがしやすくなります。
- ブラウザの開発者ツールの「ネットワーク」で、同意前に CDP への通信が発生していないか
- 同意後、page とクリックのイベントがデバッグ画面に届くか、プロパティ名がトラッキングプランどおりか
- テスト用アカウントで登録・ログインし、identify のユーザーIDが
wp_付きの形式で届くか - ステージングとは別のソースを使うか、本番以外では読み込まない設定になっているか
まとめ
- CDP は複数のソースのデータを集めて各ツールへ配る仕組み。WordPress では計測タグの集約に役立つ
- 実装前にイベント名・プロパティ・送る側を決めたトラッキングプランを作る
- ブラウザ側は管理画面からコピーした公式スニペットを
wp_enqueue_scriptで読み込み、track と identify を送る - 会員登録や注文完了は
user_registerやwoocommerce_order_status_completedからサーバー経由で送り、二重送信を防ぐ - 同意を得るまで読み込まず、メールアドレスなどの個人情報は必要な場合だけ、説明したうえで送る