gtm-setup について
gtm-setup は、Google Tag Manager のイベント計測を実装し、タグ、トリガー、変数を設定するためのリファレンススキルです。マーケターや開発者向けに、例とトラブルシューティングを提供します。
主な機能
- 01dataLayer イベント例
- 02トリガーと変数のリファレンス
- 03GA4 タグ設定ガイド
- 04デバッグとトラブルシューティング
- 05実装のベストプラクティス
活用シーン
- 01EC イベント計測の設定
- 02SPA のページ変更トリガー設定
- 03GTM Preview でのタグデバッグ
- 04dataLayer 値の GA4 イベントへのマッピング
MCP 対応
Cogny GTM MCP ツールが利用できる場合、GTM コンテナ内のタグ、トリガー、変数を確認できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cognyai/ claude-code-marketing-skills --skill gtm-setupインストール後、Claude Code で/gtm-setupを入力して読み込まれたか確認します。
詳細
GTM イベントトラッキングとセットアップのリファレンス
Google タグマネージャーのイベントトラッキングに関する完全なリファレンスガイドです。dataLayer の基本、トリガーと変数の種類、GA4 タグの設定、デバッグモード、実装のベストプラクティスを網羅しています。
ドキュメント全文:https://cogny.com/docs/gtm-event-tracking
使用方法
/gtm-setup # Full GTM reference overview
/gtm-setup dataLayer # dataLayer fundamentals and syntax
/gtm-setup purchase # Show purchase event dataLayer.push()
/gtm-setup triggers # All trigger types explained
/gtm-setup variables # All variable types explained
/gtm-setup tags # GA4 tag configuration
/gtm-setup debug # Debug mode and troubleshooting
/gtm-setup best practices # Naming conventions, organization
/gtm-setup common mistakes # Race conditions, missing data, duplicates
指示
あなたは Google タグマネージャーのエキスパートです。このリファレンスを使って、イベントトラッキングの実装、タグ/トリガー/変数の設定、GTM の問題のデバッグ、ベストプラクティスの遵守をユーザーに支援してください。
ユーザーから質問されたら、以下から関連するセクションを見つけ、すぐに使えるコードスニペットとともに、正確で実践的な回答を提供してください。
ユーザーが特定のトピックを引数として指定した場合は、その分野に焦点を当ててください。指定がない場合は、GTM の概念を概説し、どのようなサポートが必要か尋ねてください。
Cogny GTM MCP ツールが利用可能な場合は、それらを使ってユーザーの実際の GTM コンテナを調査し、タグ/トリガー/変数の一覧を確認して、実際の設定に基づいた推奨事項を提示してください。
dataLayer の基本
dataLayer とは?
dataLayer は、ウェブサイトと GTM の間でメッセージをやり取りする JavaScript 配列です。dataLayer にオブジェクトをプッシュすると、GTM はそれを読み取り、トリガーを発火させ、変数に値を設定します。
初期化
早い段階でのプッシュを取り込めるよう、GTM スニペットより前に dataLayer を宣言してください。
<script>
window.dataLayer = window.dataLayer || [];
</script>
dataLayer.push() の構文
// Push data AND fire a trigger (event key is required for trigger evaluation)
dataLayer.push({
'event': 'custom_event_name',
'key1': 'value1',
'key2': 'value2'
});
// Push data without firing a trigger (no 'event' key)
dataLayer.push({
'user_type': 'premium',
'user_id': '12345'
});
オブジェクトの保持とマージ
後からプッシュされた値が、それより前の値を上書きします。ネストされたオブジェクトは浅いマージを使用します(ネストされたオブジェクト全体が置き換えられ、ディープマージはされません)。
dataLayer.push({ 'user': { 'name': 'John', 'plan': 'free' } });
dataLayer.push({ 'user': { 'plan': 'premium' } });
// Result: user = { plan: 'premium' } — user.name is GONE
古いデータのクリア(E コマースでは重要)
古いデータの混入を防ぐため、E コマースイベントの前には必ず null をプッシュしてください。
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'view_item',
'ecommerce': {
'items': [{ 'item_id': 'SKU-001', 'item_name': 'Blue T-Shirt', 'price': 29.99 }]
}
});
よく使われる dataLayer イベント
page_view
dataLayer.push({
'event': 'page_view',
'page_location': window.location.href,
'page_title': document.title,
'page_referrer': document.referrer,
'content_group': 'blog'
});
SPA(React、Next.js、Vue)の場合は、ルート変更時に発火させます。
useEffect(() => {
dataLayer.push({
'event': 'page_view',
'page_location': window.location.href,
'page_title': document.title
});
}, [location.pathname]);
purchase
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'purchase',
'ecommerce': {
'transaction_id': 'T-20250211-001',
'value': 149.97,
'tax': 12.50,
'shipping': 5.99,
'currency': 'USD',
'coupon': 'SUMMER20',
'items': [
{
'item_id': 'SKU-001',
'item_name': 'Blue T-Shirt',
'item_brand': 'BrandName',
'item_category': 'Apparel',
'item_category2': 'T-Shirts',
'item_variant': 'Blue',
'price': 29.99,
'quantity': 2
},
{
'item_id': 'SKU-045',
'item_name': 'Running Shoes',
'item_brand': 'BrandName',
'item_category': 'Footwear',
'item_variant': 'Black/Size-10',
'price': 89.99,
'quantity': 1
}
]
}
});
add_to_cart
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {
'currency': 'USD',
'value': 29.99,
'items': [{
'item_id': 'SKU-001',
'item_name': 'Blue T-Shirt',
'item_brand': 'BrandName',
'item_category': 'Apparel',
'price': 29.99,
'quantity': 1
}]
}
});
remove_from_cart
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'remove_from_cart',
'ecommerce': {
'currency': 'USD',
'value': 29.99,
'items': [{
'item_id': 'SKU-001',
'item_name': 'Blue T-Shirt',
'price': 29.99,
'quantity': 1
}]
}
});
view_item
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'view_item',
'ecommerce': {
'currency': 'USD',
'value': 29.99,
'items': [{
'item_id': 'SKU-001',
'item_name': 'Blue T-Shirt',
'item_brand': 'BrandName',
'item_category': 'Apparel',
'price': 29.99
}]
}
});
view_item_list
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'view_item_list',
'ecommerce': {
'item_list_id': 'category_apparel',
'item_list_name': 'Apparel',
'items': [
{ 'item_id': 'SKU-001', 'item_name': 'Blue T-Shirt', 'index': 0, 'price': 29.99 },
{ 'item_id': 'SKU-002', 'item_name': 'Red T-Shirt', 'index': 1, 'price': 29.99 }
]
}
});
begin_checkout
dataLayer.push({ ecommerce: null });
dataLayer.push({
'event': 'begin_checkout',
'ecommerce': {
'currency': 'USD',
'value': 149.97,
'coupon': 'SUMMER20',
'items': [
{ 'item_id': 'SKU-001', 'item_name': 'Blue T-Shirt', 'price': 29.99, 'quantity': 2 },
{ 'item_id': 'SKU-045', 'item_name': 'Running Shoes', 'price': 89.99, 'quantity': 1 }
]
}
});
form_submit
dataLayer.push({
'event': 'form_submit',
'form_id': 'contact_form',
'form_name': 'Contact Us',
'form_destination': '/thank-you'
});
generate_lead
dataLayer.push({
'event': 'generate_lead',
'currency': 'USD',
'value': 50.00,
'lead_source': 'contact_form'
});
sign_up / login
dataLayer.push({ 'event': 'sign_up', 'method': 'google' });
dataLayer.push({ 'event': 'login', 'method': 'email' });
search
dataLayer.push({
'event': 'search',
'search_term': 'blue t-shirt',
'search_results_count': 42
});
scroll(カスタム)
dataLayer.push({
'event': 'scroll',
'percent_scrolled': 90
});
動画イベント
// video_start
dataLayer.push({
'event': 'video_start',
'video_title': 'Product Demo',
'video_url': 'https://youtube.com/watch?v=abc123',
'video_provider': 'youtube',
'video_duration': 180
});
// video_progress
dataLayer.push({
'event': 'video_progress',
'video_title': 'Product Demo',
'video_percent': 50,
'video_current_time': 90,
'video_duration': 180
});
// video_complete
dataLayer.push({
'event': 'video_complete',
'video_title': 'Product Demo',
'video_duration': 180
});
トリガーの種類
ページビュー トリガー
| サブタイプ | 発火するタイミング | 用途 |
|---|---|---|
| ページビュー | gtm.js(即時) | GA4 設定タグ、同意チェック |
| DOM Ready | gtm.dom(DOM の解析後) | DOM 要素を読み取るタグ |
| ウィンドウ読み込み完了 | gtm.load(すべてのリソース読み込み後) | 画像/スクリプトに依存するタグ |
ページパス、ページホスト名、またはページ URL で絞り込みます。
クリック トリガー
| サブタイプ | 発火するタイミング | 用途 |
|---|---|---|
| すべての要素 | 任意の要素がクリックされたとき | ボタン、div、画像 |
| リンクのみ | <a> 要素がクリックされたとき | 外部リンク、ダウンロード |
使用できる変数:クリック要素、クリッククラス、クリック ID、クリックターゲット、クリック URL、クリックテキスト。
カスタムイベント トリガー
特定の event 値が dataLayer にプッシュされたときに発火します。イベント名には event キーの値と一致する名前を設定します。正規表現に対応しています(例:form_submit.*)。
dataLayer.push({ 'event': 'form_submit' });
// Fires trigger where Event Name = "form_submit"
要素の表示トリガー
要素がビューポートに入ったときに発火します。
| 設定 | 説明 |
|---|---|
| 選択方法 | CSS セレクターまたは要素 ID |
| 発火するタイミング | ページごとに 1 回/要素ごとに 1 回/表示のたび |
| 最低表示率 | デフォルトは 50% |
| 画面内に表示される最低時間 | ミリ秒 |
タイマー トリガー
設定した間隔(ミリ秒)で発火します。発火回数に上限を設定できます。
スクロール距離トリガー
指定したスクロールしきい値(割合またはピクセル数)に達すると発火します。縦方向と横方向に対応しています。
変数:スクロール距離のしきい値、スクロール距離の単位、スクロール方向。
YouTube 動画トリガー
埋め込み YouTube 動画を標準でサポートします。次のイベントを取得します:開始、完了、一時停止、シーク中、バッファリング、再生進捗(設定可能なしきい値)。
変数:動画プロバイダー、動画ステータス、動画 URL、動画タイトル、動画の長さ、動画の現在時刻、動画の再生率、動画の表示状態。
フォーム送信トリガー
フォーム送信時に発火します。オプション:タグを待機(送信を最大 2000ms 遅延)、入力内容の検証(ブラウザーの検証に合格した場合のみ発火)。
変数:フォーム要素、フォームクラス、フォーム ID、フォームターゲット、フォーム URL、フォームテキスト。
履歴変更トリガー
URL フラグメントの変更、または pushState/replaceState 時に発火します。SPA で不可欠です。
変数:新しい履歴フラグメント、古い履歴フラグメント、新しい履歴ステート、古い履歴ステート、履歴のソース。
トリガーグループ
複数のトリガーを組み合わせます。ページのライフサイクル中にグループ内のすべてのトリガーが少なくとも一度発火した場合にのみ、タグが発火します。
変数の種類
データレイヤー変数
キー名を指定して dataLayer から値を読み取ります。ネストされた値にはドット記法を使用します(例:ecommerce.transaction_id)。必ずバージョン 2 を使用してください。
JavaScript 変数
グローバル JavaScript 変数を読み取ります(例:document.title、navigator.language)。
DOM 要素変数
CSS セレクターまたは ID で指定した DOM 要素のテキストコンテンツまたは属性を読み取ります。
URL 変数
URL の構成要素を抽出します:完全な URL、プロトコル、ホスト名、ポート、パス、クエリ(オプションでクエリキーを指定)、フラグメント。
定数変数
固定値を格納します。タグ間で共有する測定 ID、ピクセル ID、設定文字列に使用します。
カスタム JavaScript 変数
無名関数を実行し、その値を返します:
// Get viewport width
function() {
return window.innerWidth;
}
// Classify page type from URL
function() {
var path = window.location.pathname;
if (path === '/') return 'homepage';
if (path.indexOf('/product/') === 0) return 'product';
if (path.indexOf('/category/') === 0) return 'category';
if (path.indexOf('/blog/') === 0) return 'blog';
if (path.indexOf('/checkout') === 0) return 'checkout';
return 'other';
}
// Read a cookie
function() {
var match = document.cookie.match(new RegExp('(^| )user_segment=([^;]+)'));
return match ? match[2] : undefined;
}
ルックアップテーブル変数
入力値(別の変数から取得)を出力値にマッピングします。例:ページパス / を Homepage に、/pricing を Pricing にマッピングします。
正規表現テーブル変数
ルックアップテーブルと同様ですが、正規表現パターンを使用します。例:^/product/.* を Product Page にマッピングします。キャプチャグループと大文字・小文字の区別設定に対応しています。
タグの種類
GA4 設定タグ
GA4 測定ストリームを設定します。すべてのページで発火させます。
| 設定 | 説明 |
|---|---|
| 測定 ID | G-XXXXXXXXXX(定数変数を使用) |
| page_view を送信 | 読み込み時に page_view を自動送信 |
| 設定するフィールド | debug_mode、send_page_view、user_id |
| ユーザープロパティ | ユーザースコープのディメンション |
GA4 イベントタグ
カスタムイベントを GA4 に送信します。
| 設定 | 説明 |
|---|---|
| 設定タグ | 使用する GA4 設定タグ |
| イベント名 | GA4 イベント名(例:generate_lead) |
| イベントパラメーター | キーと値のペア(例:transaction_id、value) |
カスタム HTML タグ
任意の HTML/JavaScript を実行します。必ず try/catch で囲んでください:
<script>
(function() {
try {
thirdPartySDK.track('event', { value: {{DLV - Value}} });
} catch (e) {
console.warn('GTM Custom HTML error:', e);
}
})();
</script>
カスタム画像タグ
ピクセルリクエスト(1x1 画像)を発火させます。トラッキングパラメーターを含む画像 URL を設定します。キャッシュ回避を有効にしてください。
組み込み変数
クリック変数
クリック要素、クリッククラス、クリック ID、クリックターゲット、クリック URL、クリックテキスト
フォーム変数
フォーム要素、フォームクラス、フォーム ID、フォームターゲット、フォーム URL、フォームテキスト
ページ変数
ページ URL、ページホスト名、ページパス、参照元
スクロール変数
スクロール深度のしきい値、スクロール深度の単位、スクロール方向
動画変数
動画プロバイダー、動画ステータス、動画 URL、動画タイトル、動画の長さ、動画の現在時刻、動画の再生率、動画の表示状態
ユーティリティ変数
イベント、環境名、コンテナ ID、コンテナバージョン、HTML ID、乱数、デバッグモード
デバッグモード
GTM プレビュー/デバッグ
GTM ワークスペースで「プレビュー」をクリックします。Tag Assistant が開き、次の情報が表示されます:
- イベントごとの発火したタグ/発火しなかったタグ
- 各イベント時点の dataLayer の状態
- 変数と解決された値
コンソールでの確認
// View entire dataLayer
console.table(dataLayer);
// Filter for specific events
dataLayer.filter(function(item) { return item.event === 'purchase'; });
// Watch pushes in real time
(function() {
var orig = dataLayer.push;
dataLayer.push = function() {
console.log('dataLayer.push:', arguments[0]);
return orig.apply(dataLayer, arguments);
};
})();
GA4 DebugView
GA4 設定タグのフィールドに debug_mode: true を追加し、GA4 管理画面 > DebugView でイベントを確認します。
ネットワークタブ
DevTools のネットワークタブで collect をフィルターし、GA4 ヒットを確認します。ペイロードのパラメーターを検証してください。
ベストプラクティス
命名規則
| 要素 | 規則 | 例 |
|---|---|---|
| タグ | [Platform] - [Action] - [Detail] | GA4 - Event - Purchase |
| トリガー | [Type] - [Condition] | CE - form_submit |
| 変数 | [Type prefix] - [Name] | DLV - Transaction ID |
| カスタムイベント | snake_case | generate_lead |
| フォルダー | プラットフォームまたは機能別 | GA4、Meta、Consent |
フォルダーの構成
GA4/
GA4 - Config - All Pages
GA4 - Event - Purchase
GA4 - Event - Add to Cart
Meta/
Meta - Pixel - Base Code
Meta - Event - Purchase
Consent/
HTML - Consent Banner Init
HTML - Consent Mode Update
ワークスペースの管理
- 各プロジェクト用に機能別ワークスペースを使用します(例:
Q1-2025-GA4-ecommerce) - バージョンを作成する前に、必ずプレビューします
- 使用していないワークスペースは削除または統合します
バージョン管理
- 重要な変更の前後にバージョンを作成します
- 説明的なバージョン名を付けます:「v42 - GA4 の e コマースチェックアウトファネルを追加」
- 公開後に問題が発生した場合は、ロールバックします
タグの順序設定
タグシーケンスを使用して、依存するタグより先にセットアップタグが配信されるようにします。同じトリガーで順序が重要な場合は、タグの配信優先度(数値が大きいほど先に配信)を使用します。
Consent Mode v2
// Default (before user choice)
dataLayer.push({
'event': 'consent_default',
'consent': {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied'
}
});
// After user grants consent
dataLayer.push({
'event': 'consent_update',
'consent': {
'ad_storage': 'granted',
'analytics_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted'
}
});
よくある間違い
1. 競合状態
dataLayer に必要なデータが入る前にタグが配信されます。対処法:ページビュー トリガーではなく、特定の event プッシュに紐づくカスタムイベントトリガーを使用します。
2. トリガーの誤った発火
特定のページではなく、すべてのページでタグが配信されます。対処法:必ずトリガーフィルターを追加します(例:Page Path が /thank-you と等しい)。
3. e コマースの null リセット漏れ
以前のプッシュからの古いデータがイベントに混入します。対処法:e コマースイベントの前に、必ず dataLayer.push({ ecommerce: null }) を実行します。
4. タグの重複
同じイベントが複数回送信されます。原因:複数のトリガー、条件が広すぎる、誤った配信オプション。対処法:「ページごとに 1 回」を使用するか、トリガー条件を見直します。
5. カスタム HTML によるページの破損
カスタム HTML 内の JS エラーにより、ほかのタグがブロックされます。対処法:すべてのカスタム HTML を try/catch で囲みます。
6. データレイヤー変数が Undefined を返す
原因:キー名の不一致(大文字と小文字を区別)、トリガーの後にデータがプッシュされる、DLV のバージョンが誤っている、ドット記法のパスが正しくない。
7. SPA のページビューが追跡されない
ルートの変更が捕捉されません。対処法:History Change トリガーを使用するか、ルート変更時にカスタム page_view イベントをプッシュします。
// Next.js App Router
'use client';
import { usePathname } from 'next/navigation';
import { useEffect } from 'react';
export function GTMPageView() {
const pathname = usePathname();
useEffect(() => {
dataLayer.push({
'event': 'page_view',
'page_location': window.location.href,
'page_title': document.title
});
}, [pathname]);
return null;
}
8. クロスドメイン トラッキングの問題
ドメインをまたぐと、ユーザーが新しいセッションとしてカウントされます。対処法:GA4 Config タグ、または GA4 管理画面 > データストリーム > ドメインの設定で、クロスドメイン リンカーを設定します。
9. プレビュー トラフィックによるアナリティクスの水増し
対処法:デバッグモードが true の場合にブロックするトリガーを追加するか、traffic_type パラメーターで内部トラフィックを除外します。
リソース
- GTM デベロッパーガイド: https://developers.google.com/tag-platform/tag-manager
- GA4 イベントリファレンス: https://developers.google.com/analytics/devguides/collection/ga4/reference/events
- GTM コミュニティギャラリー: https://tagmanager.google.com/gallery
- Consent Mode: https://developers.google.com/tag-platform/security/guides/consent
- Cogny ドキュメント全文: https://cogny.com/docs/gtm-event-tracking