ad-tracking について
Webアプリに広告分析とコンバージョントラッキングを導入するためのリファレンススキルです。同意管理、イベント設計、ユーザー識別、購入計測を扱い、GA4、Google Ads、Meta Pixel、LinkedIn Insight Tagを対象とします。
主な機能
- 01Consent Mode v2の設定
- 02GA4とGoogle Adsの構成
- 03Meta PixelとLinkedIn Insight Tagの導入
- 04標準イベントとパラメーターの対応付け
- 05ユーザー識別と購入イベントの重複排除
活用シーン
- 01同意管理付き分析タグの追加
- 02SaaS登録・チェックアウトの計測
- 03購入コンバージョンのレポート設定
- 04重複イベントや誤帰属の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ssheleg/ sheleg-dev --skill ad-trackingインストール後、Claude Code で/ad-trackingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
fixtures/assert-dedup-contract.mjsmanifest.jsonpurchase-capi-from-thank-you-page.jsonpurchase-capi-server.jsonpurchase-pixel-browser.jsonREADME.mdreference-emitter.mjsreferences/consent-mode.mdevent-tracking.mdgtag-api.mdmeta-linkedin.mdperformance-security.md詳細
広告分析とコンバージョントラッキングの統合
適切な同意管理、標準イベントのマッピング、ユーザー識別、GDPR/DMA への準拠を備えて、Google Analytics 4、Google Ads、Meta(Facebook)Pixel、LinkedIn Insight Tag をウェブアプリケーションに統合するための完全なリファレンスです。
このスキルの対象範囲
GA4、Google Ads、Meta Pixel、LinkedIn Insight Tag をすべて Consent Mode
v2 のもとで扱います。基本的なセットアップと注意点は本文で説明し、
テーブル、スキーマ、フレームワークごとの配線方法は、末尾に記載した
references/ にあります。
アーキテクチャの概要
最新の広告分析スタックは、すべて同じ同意状態を尊重する必要がある複数のピクセル/タグで構成されます。アーキテクチャは次のパターンに従います。
┌──────────────────────────────────────────────────────────┐
│ CONSENT LAYER │
│ Cookie Consent Banner → localStorage → consent state │
│ All pixels gated by the same consent storage key │
└────────────────────┬─────────────────────────────────────┘
│ granted / denied
┌───────────────┼──────────────────┬──────────────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌────────────┐ ┌──────────────┐ ┌────────────┐
│ GA4 + │ │ Meta │ │ LinkedIn │ │ Mixpanel │
│ Google │ │ Pixel │ │ Insight │ │ (product │
│ Ads │ │ (fbq) │ │ Tag │ │ analytics)│
└─────────┘ └────────────┘ └──────────────┘ └────────────┘
│ │ │ │
▼ ▼ ▼ ▼
Consent Consent-gated Consent-gated Consent-gated
Mode v2 (render only (render only (opt_in /
(built-in) when granted) when granted) opt_out)
重要な原則: GA4 は独自の組み込み Consent Mode v2(デフォルトは拒否、同意時に更新)を使用します。他のすべてのピクセル(Meta、LinkedIn、Mixpanel)は、同意を条件とするパターンを使用します。つまり、ユーザーが同意するまでは一切レンダリングされません。共有の CustomEvent により、ページを再読み込みせずに同意を動的に変更できます。
同意
7 種類すべての同意シグナル、Advanced モードと Basic モード、地域別のデフォルト設定、詳細な同意、GTM の配線方法については、references/consent-mode.md を参照してください。
Consent Mode v2 は、2024 年 3 月以降、EU/EEA で必須です。
順序がすべてです。順序を間違えても、気づきにくいものです。
1. dataLayer init + gtag() stub
2. gtag('consent', 'default', { …'denied', wait_for_update: 500 })
3. restore a stored decision → gtag('consent', 'update', …)
4. load gtag.js (async)
5. gtag('js', new Date()) + gtag('config', TAG_ID)
手順 1~3 は、gtag.js の読み込み前に同期的に実行する必要があります。スクリプトの読み込み後にデフォルトを設定するページは、同意を受け入れる操作から始まるすべてのテストでは正しく見えますが、拒否したユーザーのデータを完全に失います。
拒否は無効化ではありません。 Advanced モードでは、Google は Cookie を使わない ping も引き続き受信し、それをもとにコンバージョンをモデル化します(Google 自身が公開している日付付きの事例では約 65~70%とされていますが、実際の値は測定するまでわかりません)。同意前の ping が自分の管轄地域で合法かどうかは、法律顧問の判断によります。Basic モードはより慎重な選択肢であり、それでも Google の一般的なモデリングを利用できます。
Google Analytics 4
セットアップ
環境変数: NEXT_PUBLIC_GA_MEASUREMENT_ID(形式:G-XXXXXXXXXX)
スクリプトの読み込み:
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
ad_storage: 'denied', ad_user_data: 'denied',
ad_personalization: 'denied', analytics_storage: 'denied',
wait_for_update: 500
});
// Restore prior consent
try {
if (localStorage.getItem('consent_key') === 'granted') {
gtag('consent', 'update', {
ad_storage: 'granted', ad_user_data: 'granted',
ad_personalization: 'granted', analytics_storage: 'granted'
});
}
} catch(e) {}
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
gtag('js', new Date());
// GA4 config carries NO allow_enhanced_conversions — that flag belongs on the
// Google Ads `AW-` tag only (see the Enhanced-conversions section); on a `G-`
// tag it enables nothing and contradicts this skill's own rule.
gtag('config', 'G-XXXXXXXXXX');
</script>
コマンドとイベント
パラメーターのスコープと優先順位を含む config/event/set/
get/consent については、references/gtag-api.md → コマンドを参照してください。また、Google Ads がインポートできる GA4 イベント名(sign_up、login、begin_checkout、purchase、generate_lead、view_item)と必須パラメーターについては、references/event-tracking.md → 推奨イベントを参照してください。
SPA のページビューは、自分で送信する場合は自動で記録されません。 拡張計測機能は、History API の変更時に page_view を発火します。ルート変更時に手動でも送信すると、ナビゲーションがすべて二重にカウントされます。手動でページビューを送信するのは、ハッシュルーティングの場合に限ってください。
SPA のページトラッキング
拡張計測機能が有効な GA4 は、History API を使って Single Page Application の page_view を自動的にトラッキングします。手動で page_view をトラッキングする必要があるのは、ハッシュルーティング(#/path)の場合のみです。同意状態は SPA のルート変更後も保持されます。
ドキュメント:
Google Ads コンバージョントラッキング
アーキテクチャ
GA4 と Google Ads は同じ gtag.js スニペットを共有します。NEXT_PUBLIC_GOOGLE_ADS_ID(形式:AW-XXXXXXXXX)が設定されている場合は、2 つ目の config 呼び出しを追加します。
gtag('config', 'G-XXXXXXXXXX'); // GA4
gtag('config', 'AW-XXXXXXXXX'); // Google Ads
どちらも同じ同意状態、ファーストパーティ Cookie、dataLayer パイプラインを共有します。
拡張コンバージョン
拡張コンバージョンでは、ハッシュ化されたユーザーデータ(メールアドレス、電話番号)を Google アカウントと照合することで、アトリビューションを改善します。設定方法:
- このフラグを使用する場合は、必ず Google Ads の設定、つまり
AW-タグに指定します。GA4 のG-タグには指定しないでください(このスキルの以前の改訂版ではG-設定に指定していましたが、Ads では何も有効になりません)。
gtag('config', 'AW-XXXXXXXXX', { allow_enhanced_conversions: true });
2026-08-30 に確認:Google の現在の設定ドキュメント(support.google.com/google-ads/answer/9888145、…/13258081)では、このフラグについての記載はなくなっています。現在の仕組みは、アカウントレベルの切り替え(手順 3)と user_data(手順 2)です。タグにすでにフラグが設定されている場合はそのままにし、G- 設定にはコピーしないでください。
- コンバージョンイベントが発火する前にユーザーデータを設定します。
gtag('set', 'user_data', {
email: '[email protected]', // Google hashes automatically
phone_number: '+1234567890', // optional
});
- Google Ads のコンソールで有効にします:目標 → コンバージョン → 設定 →
拡張コンバージョン → 「拡張コンバージョンを有効にする」(2026-08-31 に
support.google.com/google-ads/answer/13258081と照合して確認済み。再設計された UI では、以前の「ツール → コンバージョン」の手順はなくなっています)
user_id(クロスデバイス トラッキング)
認証後に GA4 の user_id を設定すると、クロスデバイス トラッキングとオーディエンスの構築が可能になります。
gtag('config', 'G-XXXXXXXXXX', {
user_id: 'USER_123',
send_page_view: false // prevent duplicate page_view
});
外部リダイレクト後の gclid の保持
Google Ads の自動タグ設定による gclid は、ファーストパーティ Cookie の _gcl_aw に保存されます(デフォルトの有効期間は約 90 日)。外部リダイレクト(Stripe Checkout → リターン URL)後も保持されます。自分のドメインの Cookie は有効期限が切れた場合にのみ削除されるため、追加のコードは不要です。2026-08-31 に確認済みです。注意点は Safari です。ITP により、JavaScript で設定された Cookie の有効期間は 7 日間に制限されます。リンクに装飾情報が付加された状態で移動した場合は 24 時間となり、gclid のランディングもこれに該当します。
Google Ads コンソールの設定
1 つの gtag ローダーを GA4 と Ads の両方に接続する方法については、references/gtag-api.md → 複数プロダクトの設定を参照してください。Ads コンソールでは、最初のクリックが発生する前にコンバージョン アクションを メインに設定し、アトリビューション期間を設定する必要があります。設定前に発生したコンバージョンは古い設定でアトリビューションされ、再計算できません。
Meta(Facebook)ピクセル
設定
環境変数: NEXT_PUBLIC_META_PIXEL_ID(数値文字列)
ベースコード(同意を条件に実行):
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}
(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'PIXEL_ID');
fbq('track', 'PageView');
noscript フォールバック — 同意を条件に実行するか、省略してください。 単独の <noscript> Meta ピクセルは、JavaScript が無効なページビューごとに発火します。バナーも fbq も同意もないまま発火するため、Meta は 同意されるまでレンダリングしないという、このスタックのルールに反します。そのため、サーバーで検証可能な同意(HTML を書き出す前にサーバーが読み取る、署名済みの HttpOnly Cookie)がすでに存在する場合に限り、サーバーから出力してください。サーバー側で同意を検証できない場合は、省略してください。Meta の検証にこれは必要なく、発火したリクエストを取り消すことはできません。
{% if consent_cookie_verified and consent.ad_storage == "granted" %}
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=PIXEL_ID&ev=PageView&noscript=1"/></noscript>
{% endif %}
ここにあるスニペットは実行可能なテンプレートに由来するため、静的チェックにより、このセクションで防ぐ 2 つの誤りを拒否します。G- タグに allow_enhanced_conversions を指定することと、サーバーで検証済みの同意条件の対象外に Meta の noscript ピクセルを置くことです。
標準イベント
Meta は 17 種類の標準イベントを定義しています。SaaS のファネルに関係するのは CompleteRegistration、InitiateCheckout、Purchase、Subscribe の 4 つで、必須パラメーターがあるのは Purchase のみです。必須パラメーターは value と currency で、これらがないと Meta は最適化できません。すべてのイベント、各イベントのパラメーター、注意点をまとめた表は、references/meta-linkedin.md → 標準イベントにあります。
Meta と LinkedIn の詳細
イベントごとのパラメーターオブジェクト、発火用ラッパー、高度なマッチング(ハッシュ化された識別子と、決して送信してはいけないデータ)、CAPI の重複排除については、references/meta-linkedin.md を参照してください。
LinkedIn Insight Tag
Meta ピクセルと同じラッパーを使用し、同意を条件に実行します。環境変数は
NEXT_PUBLIC_LINKEDIN_PARTNER_ID です。コンバージョンはコードではなく Campaign Manager で設定するため、重複排除の必要はなく、バンドル内で気付かれないまま失敗することもありません。ただし、更新可能なページに URL ルールを設定すると、更新のたびにカウントされます。設定用スニペット、Campaign Manager の手順、lintrk については、references/meta-linkedin.md → LinkedIn コンバージョン トラッキングを参照してください。
ユーザー識別
誤るとデータが失われるのではなく、アトリビューションが破損するため、本文では次のルールを守ります。追跡する前に識別し、追跡した後に識別してはいけません。匿名 ID で発火したイベントを後から再アトリビューションすると、すでに取り込んだすべてのプラットフォームで、2 人のユーザーとして扱われます。プラットフォームごとの戦略、Mixpanel の alias と identify の違い、タイミングのルールについては、references/event-tracking.md → ユーザー識別を参照してください。
イベントの命名
references/event-tracking.md → 推奨イベントとパラメーターのルールを参照してください。GA4 では一部の名前が予約されており、重複するイベントは通知なく破棄されます。どの名前が該当するかは、リファレンスに記載されています。
E コマース
GA4 のアイテムスキーマと、purchase/add_to_cart/begin_checkout の全イベントセットについては、references/event-tracking.md → E コマースイベントを参照してください。
収益が通知なく二重計上される原因は、重複排除の設定です。 ブラウザーとサーバー(Conversions API、サーバーサイド GA4)の両方から発火する購入イベントには、同じ event_id/transaction_id を設定する必要があります。そうしないと両方が計上されます。サンキューページを再読み込みするのではなく、fixtures/assert-dedup-contract.mjs を実行してください。pixel-and-capi-carry-one-event-id と pixel-and-capi-carry-one-event-name は、一方のフィールドだけを共有するエミッターを失敗と判定します。no-purchase-reported-before-the-charge-cleared は、リダイレクトから報告するエミッターを失敗と判定し、the-browser-event-is-kept は、ピクセルを削除するエミッターを失敗と判定します。--self-test を指定すると、各ルールを削除し、対応するアサーションが失敗することを確認できます。
購入はブラウザーイベントではありません。そのため、どこから発生させるかが決まります。 リストにある他のイベントはすべて、ユーザーがタブ内で行った操作なので、ブラウザーが自然な発生元です。購入は決済システム内で正常に完了した請求の結果であり、成功を把握しているのはプロバイダーの webhook だけです。サンキューページから発火すると、請求が完了したかどうかを把握していない唯一の場所から発火することになります。その結果、ページに到達したすべてのセッションで購入イベントが発生し、返金イベントは一件も発生しなくなります。
そのため、優先順位は好みではなく、順序で決まります。
- 購入の信頼できる情報源は webhook ハンドラーです。 このハンドラーが利用権を書き込み、同じハンドラーからサーバーサイドのコンバージョンを送信します。売上を記録する場所がハンドラーなら、イベントもそこで発生させます。
- ブラウザーイベントは残し、あくまで補助的に扱います。 クリック ID、同意状態、セッションなど、ブラウザーだけが持つアトリビューションシグナルのために残し、サーバーが再利用する
event_idを設定します。両者が食い違う場合は、サーバーを正とします。 - ブラウザーで失われるものはすべて、金銭に最も近いところで失われます。 ブロッカー、リダイレクト時にモバイルブラウザーがタブを終了すること、戻りの処理より前に決済プロバイダーのホストページがセッションを終了することなどは、いずれも最後のステップから優先的に取り除きます。そのため、ブラウザーのみで計測した購入数は、ブラウザー内からは測定できない分だけ少なく偏ります。
分析ダッシュボードではなく、決済プロバイダーと照合してください。期間中に成功した請求件数は決済システムから正確に取得でき、このイベントについて、それ自体がテレメトリーではない唯一の外部確認手段です。この照合でほかに何が明らかになるかについては、stripe-billing → 単一のプロバイダーへの依存を参照してください。
コンテンツセキュリティポリシー
プラットフォームごとのディレクティブ一式については、references/performance-security.md → コンテンツセキュリティポリシーを参照してください。
落とし穴: gtag ローダーに nonce を設定するだけでは不十分です。Google は実行時に追加のスクリプトを挿入するため、script-src にも Google のドメインが必要です。また、ランディングページで問題なく機能する CSP でも、Ads のコンバージョンタグが読み込まれるチェックアウトで問題が起きることがあります。
Next.js
コンポーネントツリーについては references/gtag-api.md → Next.js / React Integration を、next/script の戦略選択と SPA のルート変更については references/performance-security.md → Script Loading
Strategies を参照してください。
どちらにも明記されていない、見落としやすい落とし穴が2つあります:
NEXT_PUBLIC_*は ビルド時にインライン化されます。Docker ビルドでは、変数をビルダーステージで設定する必要があります。実行時に注入すると、バンドルには文字列がそのまま残り、すべてのイベントがどこにも送信されません。- 認証が必要なエリアと埋め込み/ウィジェットページでは、異なる条件設定が必要です。ダッシュボードにはすでに同意設定がありますが、埋め込みページにはない可能性があり、親ページの設定を前提にしてはいけません。
UTM アトリビューション
取得フロー(localStorage から OAuth リダイレクトを経て DB に保存)、5つのパラメーターの表、プラットフォームのクリック ID(gclid/fbclid/li_fat_id)については、references/event-tracking.md → UTM Attribution を参照してください。これらは SDK が自動的に処理するため、URL から削除しないでください。
検証
プラットフォームごとの完全なチェックリスト(GA4 DebugView、Meta Test Events、LinkedIn tag helper)と同意設定の往復については、references/performance-security.md → Debug & Testing を参照してください。
大半の問題を検出できるチェック方法: 新しいシークレットウィンドウでサイトを開き、同意を拒否して、DevTools → Network で _ga または _gcl_* Cookie が設定されていないこと、および collect リクエストに gcs=G100 が含まれていることを確認してください。同意した後は正しく発火するものの、拒否時のデフォルト設定を無視するタグこそ、このスキルが防ごうとしている問題です。同意を受け入れるところから始めるテストでは、どれも問題がないように見えてしまいます。
トラブルシューティング
よくある問題の表(同意設定の順序、PageView の重複、Advanced/Enhanced Matching のタイミング、localhost ガード)とデバッグモードのスニペットについては、references/performance-security.md → Troubleshooting を参照してください。特によくある問題は次の2つです。同意の default は gtag.js の読み込み前に実行する必要があります。また、value/currency のない購入イベントは、どちらのプラットフォームでも最適化の対象にできません。
公式ドキュメント
Google:Consent Mode v2 · gtag.js · GA4 events。 Meta:Pixel · Conversions API。 LinkedIn:Insight Tag。 コンプライアンス:EU DMA。
詳細リファレンス
上記のセクションでは4つのプラットフォームにまたがる統合の概要を説明しています。以下の各ファイルでは、このファイルでは意図的に扱っていない詳細を説明しています。各ファイルの冒頭にはそれぞれ Load this when の行があり、参照する条件を一か所にまとめ、この表をインデックスとして使えるようにしています。
| ファイル | 参照するタイミング |
|---|---|
references/consent-mode.md | 同意設定が作業対象の場合 |
references/gtag-api.md | gtag を直接呼び出す場合 |
references/event-tracking.md | イベントスキーマを設計する場合 |
references/performance-security.md | タグが Lighthouse のスコアを下げる、または CSP で失敗する場合 |
references/meta-linkedin.md | 作業対象が Google ではなく Meta または LinkedIn の場合 |
同じ問題のページ速度に関する側面、つまりタグが LCP と TBT に与える影響と、その対処方法については、このパックの frontend-performance スキルを参照してください。
制限事項
- Claude Code 以外の場合(Cursor、Codex、skills CLI、API コンテナー):このパックの
PreToolUseゲートは実行されません。このパックでは、ライブキーや 取り消せない操作を拒否する役割を担いますが、ほかの環境では、これらのルールを手動で守る必要があります。 - プラグインではなくコピーでインストールした場合:教義は含まれますが、
hooks/は含まれません。 — 同じものが失われ、対処法も同じです。 - ネットワークに接続できない場合、または広告プラットフォームの API に到達できない場合:サーバーサイドイベントをエンドツーエンドで検証できません。重複排除チェックが実行されなかったと伝え、正常に機能したとは報告しないでください。 ブラウザピクセルの発火で確認できるのはブラウザの動作だけであり、コンバージョンではありません。
トリガー
ここに誘導されるほかのフレーズ:「広告トラッキング」、「fbq」、「google ads」、「gtag」、「Cookie 同意」、 「エンハンストコンバージョン」、「リターゲティング」、「購入イベント」、「gclid」、「UTM」、「アトリビューション」、 「クッキーへの同意」、「広告分析」。
0.16.2 の説明からここに移動しました:「コンバージョントラッキング」。