GTMのデータレイヤーエラー完全ガイド|タグが発火しない原因と解決法

「GTMでタグを設定したのに発火しない…」「データレイヤーでundefinedエラーが出る…」そんな悩みを抱えていませんか?

Google Tag Manager(GTM)のデータレイヤー周りのエラーは、Web広告運用やアクセス解析の精度を著しく低下させる深刻な問題です。しかし、エラーの原因は「定義の問題」「タイミングの問題」「名前・構造の不一致」「GTM側設定ミス」の4つに集約されます。

本記事では、GTMのデータレイヤーでよくハマる典型的なエラーの原因と、それぞれの具体的な解決方法を徹底解説します。プレビューモードを使ったデバッグ手順から、eコマーストラッキングの正しい実装方法まで、実践的な内容をコード例付きで紹介します。

この記事を読めば、データレイヤーエラーを自力で解決し、正確なデータ収集環境を構築できるようになります。


GTMデータレイヤーでよくある4大エラー原因

GTMのデータレイヤーで発生するエラーは、大きく4つのカテゴリに分類できます。これらを理解することで、エラー発生時に原因を素早く特定し、適切な対処ができるようになります。ここでは、それぞれのエラー原因について、発生する仕組みと具体的な解決方法を詳しく解説します。

dataLayer is not defined エラーの原因と対処法

結論: dataLayer is not defined エラーは、dataLayer.push()を実行する前にdataLayerが定義されていないことが原因です。

このエラーが発生する主な理由は、JavaScriptの読み込み順序の問題です。Webページは上から下へ順番に読み込まれるため、GTMコンテナスニペットよりも後ろにdataLayerの初期化コードを配置してしまうと、GTMがdataLayerを参照しようとした時点ではまだ存在せず、エラーが発生します。

正しい実装方法:

<!-- 1. headタグ内の最初にdataLayerを初期化 -->
<script>
  window.dataLayer = window.dataLayer || [];
</script>

<!-- 2. その後にGTMコンテナスニペット -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];...})</script>

<!-- 3. 必要に応じてdataLayer.push()を実行 -->
<script>
  dataLayer.push({
    'pageCategory': 'product',
    'productId': '12345'
  });
</script>

重要なポイント:

  • window.dataLayer = window.dataLayer || []; は必ずGTMスニペットより上に配置する
  • ||演算子により、既にdataLayerが存在する場合は上書きせず、存在しない場合のみ空配列を作成する
  • この初期化を行わないと、ブラウザのコンソールに「Uncaught ReferenceError: dataLayer is not defined」というエラーが表示されます

データレイヤーの上書き問題

結論: dataLayerを配列ではなくオブジェクトで代入すると、GTM側のdataLayerと別物になりタグが発火しなくなります。

開発者がよく陥るミスとして、var dataLayer = [{...}] のように配列を新規作成してしまうケースがあります。この書き方は一見正しく見えますが、GTMが管理しているdataLayer配列を完全に上書きしてしまうため、GTMとの連携が切れてしまいます。

間違った例:

// ❌ これは危険 - GTMのdataLayerを上書きしてしまう
var dataLayer = [{
  'event': 'purchase',
  'transactionId': 'T12345'
}];

正しい例:

// ✅ 正しい方法 - pushメソッドで追加
dataLayer = dataLayer || [];
dataLayer.push({
  'event': 'purchase',
  'transactionId': 'T12345'
});

pushメソッドを使うべき理由:

  • 既存のdataLayerに新しい情報を追加する形になる
  • GTMが管理している配列の参照を維持できる
  • 複数のdataLayer.push()を実行しても、すべてのデータが保持される

対策のチェックリスト:

項目確認内容
初期化dataLayer = dataLayer || []; の形式で記述しているか
追加dataLayer.push({...}) でデータを追加しているか
代入禁止dataLayer = [...] のような直接代入をしていないか

3. タイミングエラー|変数がundefinedになる原因

結論: dataLayer.push()の実行タイミングがGTMのタグ発火より遅いと、変数がundefinedになります。

このエラーは、データレイヤーに値が設定される前にGTMがその値を取得しようとすることで発生します。特に「Page View」トリガーを使用している場合、ページ読み込みの初期段階でタグが発火するため、後からJavaScriptで設定されるdataLayer変数を取得できません。

発生する典型的なパターン:

  1. フッターでのdataLayer構築問題
    • CMSやテンプレートエンジンがフッター部分でdataLayerを出力している
    • Page Viewトリガーの発火時点ではまだdataLayerが存在しない
    • 結果として変数が取得できず「undefined」になる
  2. SPAサイトでの仮想ページビュー
    • シングルページアプリケーションでは通常のページ遷移が発生しない
    • 新しいページに移動してもdataLayerが更新されない
    • History Changeイベントに合わせてdataLayer.push()を実装する必要がある

解決方法:

// ❌ 問題のあるコード - フッターで実行
<footer>
  <script>
    dataLayer.push({
      'pagePostAuthor': 'John Doe',
      'pageCategory': 'blog'
    });
  </script>
</footer>
// ✅ 改善されたコード - headタグ内で実行
<head>
  <script>
    window.dataLayer = window.dataLayer || [];
    dataLayer.push({
      'pagePostAuthor': 'John Doe',
      'pageCategory': 'blog'
    });
  </script>
  <!-- GTMスニペット -->
</head>

トリガータイプの変更による対処:

トリガータイプ発火タイミング適用ケース
Page Viewページ読み込み開始直後dataLayerがhead内にある場合
DOM ReadyDOM構築完了時dataLayerがbody内にある場合
Window Loadedすべてのリソース読み込み完了後dataLayerがfooter内にある場合
カスタムイベントdataLayer.push({event: ‘xxx’})実行時確実にデータが揃った後に発火させたい場合

SPAサイトでの実装例:

// React Router使用時の例
dataLayer.push({
  'event': 'virtualPageview',
  'pagePath': '/new-page',
  'pageTitle': '新しいページ'
});

変数名・構造の不一致エラー

結論: dataLayerのキー名とGTM変数名が完全一致していない場合、変数が取得できずundefinedになります。

JavaScriptは大文字小文字を区別する言語です。そのため、dataLayerでpagePostAuthorというキーを使用しているのに、GTM側の変数名をpagepostauthorと設定してしまうと、変数は取得できません。また、ネスト構造の階層が異なる場合も同様にエラーが発生します。

よくあるミスの例:

  1. スペルミス・大文字小文字の違い
dataLayer側GTM変数名結果
pagePostAuthorpagePostAuthor✅ 正常に取得
pagePostAuthorpagepostauthor❌ undefined
user_iduserId❌ undefined
  1. ネスト構造の不一致
// dataLayer側の構造
dataLayer.push({
  'user': {
    'id': '12345',
    'name': 'John Doe'
  }
});
// GTM側の設定
❌ 間違い: データレイヤー変数名 = "user"(オブジェクト全体が返る)
✅ 正しい: データレイヤー変数名 = "user.id"(値が返る)
  1. eコマーストラッキングの構造違い

GA4とユニバーサルアナリティクスでは、ecommerceオブジェクトの構造が異なります。両方の形式が混在していると、GA4では正しく計測できません。

ユニバーサルアナリティクス形式(旧):

dataLayer.push({
  'ecommerce': {
    'purchase': {
      'actionField': {
        'id': 'T12345'
      },
      'products': [{
        'name': 'Product Name',
        'id': 'P12345'
      }]
    }
  }
});

GA4形式(新):

dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'transaction_id': 'T12345',
    'value': 25.42,
    'currency': 'JPY',
    'items': [{
      'item_id': 'P12345',
      'item_name': 'Product Name',
      'price': 25.42
    }]
  }
});

確認方法:

  1. ブラウザのコンソールで console.log(dataLayer) を実行
  2. キー名を正確に確認し、GTM側の変数名と完全一致させる
  3. ネスト構造がある場合は、ドット記法で階層を指定する(例: ecommerce.items.0.item_id

GTM側の設定ミスでタグが発火しないパターン

データレイヤー側の実装が正しくても、GTM側の設定に問題があるとタグは発火しません。ここでは、GTM管理画面での典型的な設定ミスとその解決方法を解説します。

コンテナIDと公開状態の確認

結論: GTMワークスペースで変更を保存しただけでは本番環境に反映されません。必ず「公開」作業が必要です。

GTMの初心者が最も陥りやすいミスが、変更を「保存」しただけで「公開」を忘れてしまうケースです。GTMでは、ワークスペース上での変更はプレビューモードでのみ確認でき、実際のWebサイトに反映させるには明示的に公開する必要があります。

確認すべきポイント:

  1. 本番と検証環境のコンテナ違い
    • 本番サイトに検証用のコンテナID(GTM-XXXXXX)を設置していないか確認
    • ページのソースコードを表示し、正しいコンテナIDが記載されているか確認
    • 複数のコンテナIDが混在していないかチェック
  2. ワークスペース更新したが未公開のケース
    • GTM管理画面の右上に「未公開の変更があります」と表示されていないか確認
    • 最終公開日時を確認し、自分の変更後に公開されているか確認
    • バージョン履歴で、どのバージョンが現在公開中か確認
  3. プレビューモードでの確認方法

手順:

  1. GTM管理画面で「プレビュー」ボタンをクリック
  2. 検証したいページのURLを入力して「Connect」
  3. 「Tag Assistant Connected」と表示されれば、正しいコンテナが読み込まれている
  4. 「Not Connected」の場合は、コンテナIDが間違っているか、GTMタグが設置されていない

公開手順:

  1. ワークスペース画面右上の「送信」ボタンをクリック
  2. バージョン名と変更内容の説明を入力(後から確認しやすい名前を推奨)
  3. 「公開」ボタンをクリックして本番環境に反映

トリガー設定の間違い

結論: トリガーのイベント名やURL条件が実際のデータと一致していない場合、タグは発火しません。

トリガーはタグを発火させる「条件」を定義するものですが、この条件設定が実際のWebサイトの動作と合っていないと、いくら待ってもタグは発火しません。

典型的なミス例:

  1. イベント名の不一致
// dataLayer側で送信しているイベント名
dataLayer.push({
  'event': 'purchase'  // ← 小文字のpurchase
});
// GTMトリガー側の設定
トリガータイプ: カスタムイベント
イベント名: Purchase  // ← 大文字のPurchase(不一致のため発火しない)

正しい設定:

  • イベント名は大文字小文字を含めて完全一致させる
  • スペルミスがないか慎重に確認
  • プレビューモードの「イベント」一覧で実際に飛んでいるイベント名を確認
  1. URL条件の設定ミス
条件タイプ設定値実際のURL発火
等しいhttps://example.com/pagehttps://example.com/page?id=123❌ パラメータがあるため不一致
含む/pagehttps://example.com/page?id=123✅ 発火する
正規表現の一致/page.*https://example.com/page-list✅ 発火する
先頭が一致https://example.com/pagehttps://example.com/page/sub✅ 発火する

カスタムイベントトリガーの正しい設定方法:

  1. GTM管理画面でトリガーを新規作成
  2. トリガータイプで「カスタムイベント」を選択
  3. イベント名にdataLayer.push()で送信しているイベント名を正確に入力
  4. 必要に応じて追加条件(URL、変数の値など)を設定
  5. プレビューモードで実際に発火するか確認

プレビューでのイベント確認手順:

  1. GTMプレビューモードを起動
  2. 検証したいページでアクションを実行(クリック、フォーム送信など)
  3. プレビュー画面左側の「イベント」一覧を確認
  4. 期待するイベントが表示されているか確認
  5. イベント名をクリックして詳細を確認
  6. その名前をトリガー設定にコピーして使用

データレイヤーエラーのデバッグ手順

データレイヤーエラーを効率的に解決するには、適切なデバッグツールと手順を知っておく必要があります。ここでは、ブラウザのデベロッパーツールやGTMプレビューモード、Chrome拡張機能を使った具体的なデバッグ方法を解説します。

ブラウザコンソールでの確認方法

結論: ブラウザのコンソールでdataLayerの中身を直接確認することで、変数名やネスト構造の問題を特定できます。

JavaScriptのコンソールは、dataLayerの状態をリアルタイムで確認できる最も基本的なデバッグツールです。プログラミングの知識がなくても、簡単なコマンドでdataLayerの内容を確認できます。

基本的な確認コマンド:

// 1. dataLayer全体を確認
console.log(dataLayer);

// 2. 最新のdataLayerオブジェクトを確認
console.log(dataLayer[dataLayer.length - 1]);

// 3. 特定のキーの値を確認
console.log(dataLayer.find(obj => obj.pageCategory));

// 4. ecommerceオブジェクトのみを抽出
console.log(dataLayer.filter(obj => obj.ecommerce));

変数名とネスト構造のチェックポイント:

  1. 大文字小文字の確認
    • コンソールに表示されたキー名を正確にコピー
    • GTM側の変数名と1文字ずつ照合
    • スペルミスや全角/半角の違いがないか確認
  2. ネスト構造の深さを確認
// 表示されたdataLayerの例
{
  "ecommerce": {
    "items": [
      {
        "item_id": "P12345",
        "item_name": "商品名"
      }
    ]
  }
}

この場合、GTM変数での指定方法:

  • ecommerce → オブジェクト全体が返る(通常は使わない)
  • ecommerce.items → 配列が返る
  • ecommerce.items.0.item_id → “P12345″が返る

実践的なデバッグ手順:

  1. ブラウザで対象ページを開く
  2. F12キーを押してデベロッパーツールを開く
  3. 「Console」タブを選択
  4. dataLayerと入力してEnterキーを押す
  5. 配列の中身を展開して、目的のデータが含まれているか確認
  6. GTM側の変数設定と照合

エラーメッセージの読み方:

エラーメッセージ原因対処法
dataLayer is not defineddataLayerが初期化されていないGTMスニペットより前にdataLayerを初期化
Cannot read property ‘xxx’ of undefinedネスト構造の途中がundefined親オブジェクトが存在するか確認
dataLayer.push is not a functiondataLayerが配列でないdataLayerを配列で初期化し直す

GTMプレビューモードの活用

結論: GTMプレビューモードを使うことで、タグの発火状況、変数の値、dataLayerの内容を視覚的に確認できます。

GTMプレビューモードは、タグマネージャーの設定が実際にどう動作するかをテストするための強力なツールです。コードを直接見なくても、グラフィカルなインターフェースで問題を特定できます。

Variables(変数)タブでの確認事項:

  1. データレイヤー変数の値を確認
    • プレビューモードを起動し、対象ページにアクセス
    • 左側のイベント一覧から確認したいイベントをクリック
    • 「Variables」タブを選択
    • 「Data Layer Variables」セクションで設定した変数の値を確認

確認ポイント:

  • 変数の値が「undefined」になっていないか
  • 期待する値が正しく表示されているか
  • 変数名のスペルミスがないか
  1. Built-In Variables(組み込み変数)の活用
組み込み変数用途確認内容
Page URLURLベースのトリガー設定現在のページURLが正しいか
Click Elementクリックイベントの要素クリックした要素のクラス名やIDが取得できているか
Form Elementフォーム送信イベントフォームのIDや action属性が取得できているか

Data Layerタブの見方:

  1. プレビューモード画面右側の「Data Layer」タブをクリック
  2. 各イベント発生時点でのdataLayerの状態を確認
  3. 「gtm.」で始まるGTM内部イベントと、カスタムイベントが混在して表示される
  4. 各オブジェクトを展開して、キーと値のペアを確認

実際の確認例:

Data Layer(イベント: purchase)
├─ event: "purchase"
├─ ecommerce
│  ├─ transaction_id: "T12345"
│  ├─ value: 25.42
│  └─ items
│     └─ [0]
│        ├─ item_id: "P12345"
│        └─ item_name: "商品名"
└─ gtm.uniqueEventId: 12

Tagsの発火状態確認:

  1. 「Tags」タブを選択
  2. 各イベントでどのタグが発火したか確認
  3. タグの状態は以下3種類で表示される:
    • Tags Fired: 正常に発火したタグ(緑色)
    • Tags Not Fired: トリガー条件に合わず発火しなかったタグ(赤色)
    • Tags Scheduled: 次に発火予定のタグ(グレー)
  4. 発火しなかったタグをクリックすると、なぜ発火しなかったかの理由が表示される

典型的な「発火しない理由」:

  • トリガー条件に一致しなかった
  • ブロッキングトリガーが作動した
  • タグの優先順位が低い
  • 前提条件(タグの順序指定)が満たされていない

Chrome拡張機能を使ったデバッグ

結論: Chrome拡張機能を使うことで、dataLayerの状態やタグの発火をリアルタイムで視覚的に確認でき、デバッグ効率が大幅に向上します。

Chrome拡張機能は、ブラウザに機能を追加することで、より便利にデバッグ作業を行えるツールです。GTMやGA4のデバッグに特化した拡張機能を使うことで、コンソールやプレビューモードでは見えにくい情報も簡単に確認できます。

おすすめChrome拡張機能:

  1. dataLayer Checker

特徴:

  • dataLayerの変更をリアルタイムで監視
  • 新しいイベントが発生するたびに通知
  • dataLayerの履歴を時系列で表示
  • イベントごとの差分を見やすく表示

使い方:

  • Chrome拡張機能ストアからインストール
  • 対象ページを開く
  • ブラウザ右上の拡張機能アイコンをクリック
  • dataLayerのイベント一覧が表示される
  • 各イベントをクリックすると詳細が確認できる

活用シーン:

  • dataLayer.push()が正しく実行されているか確認
  • イベントの発火順序を確認
  • 複数のイベントが連続して発生する場合のデバッグ
  1. Tag Assistant Legacy

特徴:

  • GoogleタグGA4、GTM、Google広告など)の発火状況を確認
  • タグの設定エラーを検出して警告
  • 複数のGoogleタグが同時に動作している場合の競合を検出

使い方:

  • 拡張機能をインストール
  • 対象ページでアイコンをクリックして「Enable」
  • ページをリロード
  • 発火したタグの一覧が色分けで表示される
    • 緑: 正常に動作
    • 青: 推奨される改善あり
    • 赤: エラーあり

エラー表示の例:

  • 「Multiple Google Analytics tags detected」(複数のGA4タグが検出された)
  • 「Missing transport mechanism」(計測IDが正しくない)
  • 「Tag is firing multiple times」(タグが複数回発火している)
  1. GA Debugger

特徴:

  • Google Analyticsのビーコン(送信データ)を詳細に表示
  • GA4のイベントパラメータを確認
  • データが正しくGoogleサーバーに送信されているか確認

使い方:

  • 拡張機能をインストールしてオンにする
  • ブラウザのコンソールを開く
  • ページ上でアクションを実行
  • コンソールにGA4のイベントデータが詳細に表示される

表示される情報:

Google Analytics Debug Output:
Event: purchase
Parameters:
  - transaction_id: T12345
  - value: 25.42
  - currency: JPY
  - items: [...]

拡張機能を使ったデバッグフロー:

  1. dataLayer Checkerでイベントの発火を確認
  2. GTMプレビューモードでタグの発火状況を確認
  3. Tag Assistant Legacyでタグの設定エラーをチェック
  4. GA DebuggerでGA4へのデータ送信を確認
  5. 問題があれば、各ツールの情報を元に原因を特定

注意点:

  • 複数の拡張機能を同時に有効にすると、相互に干渉する場合がある
  • デバッグ完了後は拡張機能をオフにする(パフォーマンスへの影響を避けるため)
  • 本番環境では必ず拡張機能をオフにしてテストする

eコマーストラッキングのdataLayer実装

GA4でeコマースイベントを正確に計測するには、dataLayerの構造を正しく理解し、適切に実装する必要があります。ここでは、GA4形式のecommerceオブジェクト構造と、よくある実装ミスについて解説します。

GA4形式のecommerceオブジェクト構造

結論: GA4のecommerceオブジェクトは、イベント名とecommerceプロパティを含むオブジェクトをdataLayer.push()で送信する形式です。

GA4のeコマース計測では、購入、カート追加、商品閲覧などのイベントごとに決められた構造でdataLayerにデータを送信する必要があります。構造が間違っていると、GA4側でデータを正しく認識できません。

必須フィールド一覧:

イベント必須フィールド説明
purchase(購入)transaction_id, value, currency, items取引ID、金額、通貨、商品配列
add_to_cart(カート追加)currency, value, items通貨、金額、商品配列
view_item(商品閲覧)currency, value, items通貨、金額、商品配列
begin_checkout(購入手続き開始)currency, value, items通貨、金額、商品配列

items配列の必須プロパティ:

プロパティ名説明
item_idstring商品ID“P12345”
item_namestring商品名“ワイヤレスマウス”
pricenumber商品単価2500
quantitynumber数量2

推奨プロパティ(設定すると分析が詳細になる):

  • item_brand: ブランド名
  • item_category: カテゴリー
  • item_category2, item_category3: サブカテゴリー
  • item_variant: バリエーション(色、サイズなど)

purchase/add_to_cart等のイベント別実装例

1. purchase(購入完了)イベント:

// 購入完了ページで実行
dataLayer.push({ ecommerce: null });  // 既存のecommerceデータをクリア
dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'transaction_id': 'T_12345',    // 注文ID(必須・ユニーク)
    'affiliation': 'オンラインストア',  // 所属(任意)
    'value': 35.43,                  // 合計金額(必須)
    'tax': 4.90,                     // 税額(任意)
    'shipping': 5.99,                // 送料(任意)
    'currency': 'JPY',               // 通貨コード(必須)
    'coupon': 'SUMMER_SALE',         // クーポンコード(任意)
    'items': [                       // 商品配列(必須)
      {
        'item_id': 'SKU_12345',      // 商品ID(必須)
        'item_name': 'ワイヤレスマウス',  // 商品名(必須)
        'affiliation': 'Google Store',
        'coupon': 'SUMMER_FUN',
        'currency': 'JPY',
        'discount': 2.22,
        'index': 0,                   // 商品リスト内の位置
        'item_brand': 'Logitech',     // ブランド
        'item_category': '電子機器',   // カテゴリー
        'item_category2': '周辺機器',  // サブカテゴリー
        'item_variant': 'ブラック',    // バリエーション
        'price': 9.99,                // 単価(必須)
        'quantity': 1                 // 数量(必須)
      },
      {
        'item_id': 'SKU_67890',
        'item_name': 'USB-Cケーブル',
        'price': 7.99,
        'quantity': 2
      }
    ]
  }
});

2. add_to_cart(カートに追加)イベント:

// 「カートに追加」ボタンクリック時に実行
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'add_to_cart',
  'ecommerce': {
    'currency': 'JPY',
    'value': 9.99,                    // 追加した商品の合計金額
    'items': [
      {
        'item_id': 'SKU_12345',
        'item_name': 'ワイヤレスマウス',
        'price': 9.99,
        'quantity': 1
      }
    ]
  }
});

3. view_item(商品詳細閲覧)イベント:

// 商品詳細ページ表示時に実行
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'view_item',
  'ecommerce': {
    'currency': 'JPY',
    'value': 9.99,
    'items': [
      {
        'item_id': 'SKU_12345',
        'item_name': 'ワイヤレスマウス',
        'item_brand': 'Logitech',
        'item_category': '電子機器',
        'price': 9.99
      }
    ]
  }
});

4. begin_checkout(購入手続き開始)イベント:

// カートページまたはチェックアウトページで実行
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'begin_checkout',
  'ecommerce': {
    'currency': 'JPY',
    'value': 35.43,                   // カート内商品の合計金額
    'coupon': 'SUMMER_SALE',
    'items': [
      {
        'item_id': 'SKU_12345',
        'item_name': 'ワイヤレスマウス',
        'price': 9.99,
        'quantity': 1
      },
      {
        'item_id': 'SKU_67890',
        'item_name': 'USB-Cケーブル',
        'price': 7.99,
        'quantity': 2
      }
    ]
  }
});

重要なポイント:

  • イベント送信前に dataLayer.push({ ecommerce: null }); で既存データをクリアする
  • eventプロパティは必ずGA4の推奨イベント名を使用する
  • 金額は数値型で送信する(文字列にしない)
  • transaction_idは購入イベントごとに一意の値にする

よくある実装ミスとその対処

結論: 旧ユニバーサルアナリティクス形式との混在、必須項目の欠落、データ型の間違いが、eコマース計測でよくあるミスです。

eコマーストラッキングの実装では、細かい設定ミスが計測精度に大きく影響します。ここでは代表的なミスパターンとその対処法を紹介します。

1. 旧ユニバーサル形式との混在

問題:

// ❌ ユニバーサルアナリティクス形式(GA4では使えない)
dataLayer.push({
  'ecommerce': {
    'purchase': {
      'actionField': {
        'id': 'T12345',
        'revenue': '35.43'
      },
      'products': [{           // GA4では'items'を使う
        'name': 'Product',     // GA4では'item_name'を使う
        'id': 'P12345',        // GA4では'item_id'を使う
        'price': '9.99'
      }]
    }
  }
});

対処法:

  • products配列をitems配列に変更
  • nameitem_nameに、iditem_idに変更
  • actionFieldを削除し、プロパティを直接ecommerceオブジェクト直下に配置
  • revenuevalueに変更

2. item_idなど必須項目の欠落

問題:

// ❌ item_idとitem_nameが欠落
dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'transaction_id': 'T12345',
    'value': 9.99,
    'currency': 'JPY',
    'items': [
      {
        'price': 9.99,         // item_idとitem_nameがない
        'quantity': 1
      }
    ]
  }
});

対処法:

  • 必須フィールド(item_id, item_name, price, quantity)を必ず含める
  • GA4のDebugViewで「必須パラメータがありません」というエラーが出ていないか確認

3. データ型の間違い

問題:

// ❌ 数値を文字列で送信してしまっている
dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'value': '35.43',          // ❌ 文字列
    'items': [
      {
        'price': '9.99',       // ❌ 文字列
        'quantity': '1'        // ❌ 文字列
      }
    ]
  }
});

対処法:

// ✅ 数値型で送信
dataLayer.push({
  'event': 'purchase',
  'ecommerce': {
    'value': 35.43,            // ✅ 数値
    'items': [
      {
        'price': 9.99,         // ✅ 数値
        'quantity': 1          // ✅ 数値
      }
    ]
  }
});

構造確認のチェックリスト:

確認項目チェック内容ツール
イベント名GA4推奨イベント名になっているかGTMプレビュー
必須フィールドitem_id, item_name, price, quantityがあるかコンソール
データ型数値が文字列になっていないかGA Debugger
ecommerceクリア前のecommerceデータがクリアされているかdataLayer Checker
items配列配列形式になっているか(オブジェクト単体ではないか)GTMプレビュー
transaction_idpurchaseイベントでユニークな値になっているかGA4 DebugView

実装前の検証手順:

  1. GTMプレビューモードでdataLayerの構造を確認
  2. ブラウザコンソールで console.log(dataLayer) を実行し、構造を目視確認
  3. GA DebuggerでGA4へのデータ送信を確認
  4. GA4のDebugViewでイベントとパラメータが正しく表示されるか確認
  5. 24時間後にGA4のレポートでデータが正しく集計されているか確認

ケース別トラブルシューティング

Webサイトの種類やCMSの仕様によって、データレイヤーエラーの発生パターンは異なります。ここでは、シングルページアプリケーション、WordPress、CMSアップデート後など、ケース別の具体的なトラブルシューティング方法を解説します。

シングルページアプリケーション(SPA)の場合

結論: SPAでは通常のページ遷移が発生しないため、History Changeイベントを活用して仮想ページビューを実装する必要があります。

シングルページアプリケーション(React、Vue.js、Angularなど)は、ページ全体をリロードせずにコンテンツを動的に更新する仕組みです。そのため、従来のページビュー計測方法では、最初のページロードしか計測できません。

SPAで発生する問題:

  • ページ遷移してもGTMの「Page View」イベントが発火しない
  • URLが変わってもdataLayerが更新されない
  • 2ページ目以降の閲覧が計測されない

仮想ページビューの実装:

// React Routerを使用している場合の例
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function App() {
  const location = useLocation();

  useEffect(() => {
    // ページ遷移時にdataLayerにイベントをpush
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      'event': 'virtualPageview',     // カスタムイベント名
      'pagePath': location.pathname,  // 新しいページパス
      'pageTitle': document.title     // ページタイトル
    });
  }, [location]);

  return <div>...</div>;
}

historyChangeListenerの活用:

GTMには「履歴の変更」というトリガータイプがあり、SPAのページ遷移を自動検出できます。

設定手順:

  1. GTMで新しいトリガーを作成
  2. トリガータイプで「履歴の変更」を選択
  3. トリガーの発火条件を設定(全ページまたは特定のURL)
  4. このトリガーを使ってGA4タグを発火させる

React/Vue.jsでの実装パターン:

Reactの場合:

// useHistoryフックを使った実装
import { useHistory } from 'react-router-dom';

const history = useHistory();

history.listen((location) => {
  window.dataLayer.push({
    'event': 'virtualPageview',
    'page': {
      'path': location.pathname,
      'title': document.title,
      'url': window.location.href
    }
  });
});

Vue.jsの場合:

// Vue Routerのafterフックを使った実装
router.afterEach((to, from) => {
  window.dataLayer.push({
    'event': 'virtualPageview',
    'pagePath': to.path,
    'pageTitle': to.meta.title || document.title
  });
});

GTM側のトリガー設定:

  • トリガータイプ: カスタムイベント
  • イベント名: virtualPageview
  • このトリガーでGA4設定タグを発火

WordPressサイトの場合

結論: WordPressではテーマやプラグインとの競合、フッター出力によるタイミング問題が発生しやすいため、子テーマでの実装と出力位置の調整が重要です。

WordPressは多くのプラグインやテーマが複雑に関わり合っているため、dataLayerの実装でも独特の問題が発生します。

テーマやプラグインとの競合:

問題パターン:

  • SEOプラグイン(Yoast SEO、All in One SEOなど)が独自のdataLayerを出力
  • キャッシュプラグインによってJavaScriptが適切に実行されない
  • テーマのJavaScriptとの読み込み順序の問題

対処法:

  1. プラグインとの競合確認:
// functions.phpで既存のdataLayer出力を無効化
remove_action('wp_head', 'some_plugin_datalayer_function');
  1. キャッシュプラグインの除外設定:
  • GTMのコンテナJavaScriptをキャッシュ対象から除外
  • dataLayer関連のスクリプトを遅延読み込み対象から除外

フッター出力される場合の対処:

問題: WordPressのテンプレートタグやプラグインがフッターでdataLayerを出力している場合、Page Viewトリガーでは値が取得できません。

確認方法:

// テーマのheader.phpまたはfooter.phpを確認
<?php wp_footer(); ?>  // この中でdataLayerが出力されている可能性

解決策:

// 子テーマのfunctions.phpに追加
function custom_datalayer_head() {
  ?>
  <script>
    window.dataLayer = window.dataLayer || [];
    dataLayer.push({
      'pageType': '<?php echo get_post_type(); ?>',
      'pageCategory': '<?php echo get_the_category()[0]->name; ?>',
      'postAuthor': '<?php echo get_the_author(); ?>'
    });
  </script>
  <?php
}
add_action('wp_head', 'custom_datalayer_head', 1);  // 優先度1で早めに実行

子テーマでの安全な実装方法:

  1. 子テーマの作成:
/wp-content/themes/
  └─ child-theme/
     ├─ style.css
     ├─ functions.php
     └─ header.php(必要に応じて)
  1. functions.phpでの実装:
<?php
// GTMコンテナコードを安全に挿入
function insert_gtm_code() {
  ?>
  <!-- Google Tag Manager -->
  <script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
  <!-- End Google Tag Manager -->
  <?php
}
add_action('wp_head', 'insert_gtm_code', 1);

// データレイヤーの出力
function insert_datalayer() {
  if (is_singular('post')) {
    // 投稿ページの場合
    ?>
    <script>
      dataLayer.push({
        'postType': 'blog',
        'postCategory': '<?php echo get_the_category()[0]->slug; ?>',
        'postDate': '<?php echo get_the_date('Y-m-d'); ?>'
      });
    </script>
    <?php
  } elseif (is_singular('product')) {
    // 商品ページの場合(WooCommerce等)
    global $product;
    ?>
    <script>
      dataLayer.push({
        'productId': '<?php echo $product->get_id(); ?>',
        'productName': '<?php echo $product->get_name(); ?>',
        'productPrice': <?php echo $product->get_price(); ?>
      });
    </script>
    <?php
  }
}
add_action('wp_head', 'insert_datalayer', 2);

注意点:

  • add_actionの優先度(第3引数)を調整して、GTMスニペットより後にdataLayerが出力されるようにする
  • PHPの変数をJavaScriptに出力する際は、XSS対策としてesc_js()を使用する
  • 子テーマを使うことで、親テーマのアップデートで変更が消えないようにする

CMSやモジュール更新後のエラー

結論: CMS更新によってdataLayerの出力位置が変わったり、テンプレート構造が変更されると、突然undefinedエラーが発生することがあります。

アップデート後にundefinedになる原因:

  1. テンプレートの変更:
    • CMSのバージョンアップでテンプレート構造が変わり、dataLayerの出力位置がフッターに移動
    • 新しいモジュールが追加され、既存のdataLayer出力と競合
  2. JavaScriptライブラリの更新:
    • jQueryなどの依存ライブラリが更新され、実行タイミングが変化
    • 非同期読み込みの仕様変更により、dataLayerの初期化が遅れる
  3. プラグインの競合:
    • 新しいプラグインが独自のdataLayerを作成
    • 既存のdataLayerを上書きしてしまう

dataLayer初期化位置の確認方法:

  1. ブラウザのデベロッパーツールで確認:
    • 対象ページで右クリック→「ページのソースを表示」
    • Ctrl+F(Windows)またはCommand+F(Mac)で「dataLayer」を検索
    • 出現箇所とGTMスニペットの相対位置を確認
  2. CMSの管理画面で確認:
    • テンプレート編集画面を開く
    • dataLayer.push()の記述がどのファイルのどの位置にあるか確認
    • アップデート前後でファイルの差分を比較

復旧手順:

ステップ1: バックアップの確認

# アップデート前のバックアップファイルを確認
# dataLayerの出力位置を確認
grep -r "dataLayer" /backup/templates/

ステップ2: dataLayerの位置を修正

<!-- ヘッダーテンプレートに移動 -->
<head>
  <script>
    window.dataLayer = window.dataLayer || [];
    // 既存のdataLayer出力をここに移動
  </script>
  <!-- GTMスニペット -->
</head>

ステップ3: トリガータイプの変更

  • GTM管理画面でトリガー設定を開く
  • 「Page View」から「DOM Ready」または「Window Loaded」に変更
  • プレビューモードで動作確認

ステップ4: 動作確認

  1. GTMプレビューモードで各ページを確認
  2. dataLayer変数が正しく取得できているか確認
  3. GA4のDebugViewでイベントが送信されているか確認
  4. 本番公開して24時間後にレポートを確認

予防策:

  • CMS更新前に必ずバックアップを取る
  • ステージング環境で先に更新して動作確認
  • dataLayer関連のコードはカスタムテンプレートや子テーマに配置
  • CMS更新後のチェックリストにGTM動作確認を含める

データレイヤーエラーを防ぐベストプラクティス

エラーが発生してから対処するよりも、最初から正しく実装してエラーを防ぐことが重要です。ここでは、実装時のチェックリスト、テスト環境での検証方法、運用中の監視とメンテナンスについて解説します。

実装時のチェックリスト

結論: 実装前にチェックリストを確認することで、よくあるミスの90%以上を防ぐことができます。

データレイヤーとGTMの実装では、細かい設定ミスが後々大きな問題になります。以下のチェックリストを活用して、実装時に確認漏れがないようにしましょう。

GTMコード配置位置:

  • [ ] GTMコンテナスニペットが<head>タグ内に配置されている
  • [ ] noscript部分が<body>タグ直後に配置されている
  • [ ] コンテナIDが正しい(本番用と検証用を間違えていない)
  • [ ] 全角文字や余分なスペースが含まれていない
  • [ ] スニペットコードが途中で切れていない

dataLayer初期化のタイミング:

  • [ ] window.dataLayer = window.dataLayer || []; がGTMスニペットより上に配置されている
  • [ ] できる限り<head>タグの最初の方に配置している
  • [ ] 複数のdataLayer初期化コードが存在しない
  • [ ] var dataLayer = [] のような直接代入をしていない
  • [ ] 非同期読み込みにしていない(同期的に実行される)

変数名の命名規則:

  • [ ] キャメルケース(camelCase)で統一されている
  • [ ] スペルミスがない
  • [ ] 全角文字を使用していない
  • [ ] 予約語(event, gtmなど)をカスタム変数名に使っていない
  • [ ] GTM側の変数名と完全に一致している(大文字小文字も含めて)

実装チェックシート(印刷用):

□ 1. GTMスニペット配置確認
  □ headタグ内に配置
  □ noscriptタグも配置
  □ コンテナID確認

□ 2. dataLayer初期化確認
  □ GTMより上に配置
  □ window.dataLayer = window.dataLayer || []; の形式
  □ 直接代入していない

□ 3. dataLayer.push()確認
  □ pushメソッドを使用
  □ オブジェクト形式で送信
  □ イベント名が正しい

□ 4. 変数名確認
  □ スペルミス なし
  □ 大文字小文字 一致
  □ GTM側と同じ名前

□ 5. eコマース実装確認
  □ GA4形式を使用
  □ 必須フィールド すべて含む
  □ データ型 正しい

□ 6. テスト実施
  □ プレビューモード 動作確認
  □ 全ページ 動作確認
  □ 主要イベント 発火確認

テスト環境での検証方法

結論: ステージング環境で十分にテストしてから本番公開することで、本番環境でのトラブルを未然に防げます。

テスト環境を活用することで、本番サイトに影響を与えずに様々なパターンを検証できます。

ステージング環境でのテスト手順:

1. 環境の準備:

  • 本番環境と同じ構成のステージング環境を用意
  • GTMの検証用コンテナを作成(本番とは別のコンテナID)
  • GA4の検証用プロパティを作成

2. 基本動作の確認:

テストケース1: ページビュー計測
□ トップページでPage Viewタグが発火
□ dataLayer変数が正しく取得できている
□ GA4 DebugViewでpageviewイベント確認

テストケース2: カスタムイベント
□ ボタンクリックでイベント発火
□ イベント名が正しい
□ パラメータが正しく送信されている

テストケース3: eコマースイベント
□ 商品詳細ページでview_itemイベント発火
□ カート追加でadd_to_cartイベント発火
□ 購入完了でpurchaseイベント発火
□ 各イベントのパラメータが正しい

3. エッジケースのテスト:

□ ページリロード時の動作
□ ブラウザバック・フォワード時の動作
□ SPAでのページ遷移時の動作
□ 複数タブを開いた時の動作
□ オフライン→オンライン復帰時の動作

本番公開前の確認項目:

段階1: ステージング環境での最終確認(公開1週間前)

  • [ ] 全ページでGTMプレビューモードによる確認完了
  • [ ] 主要な導線(トップ→商品→カート→購入)で動作確認
  • [ ] GA4のDebugViewで24時間データ監視
  • [ ] 異常なデータや欠損がないことを確認

段階2: 本番環境での限定公開テスト(公開3日前)

  • [ ] 本番GTMコンテナのプレビューモードで確認
  • [ ] 実際の本番URLで動作確認
  • [ ] 本番GA4プロパティのDebugViewで確認
  • [ ] 社内メンバーで複数ブラウザ・デバイスでテスト

段階3: 本番公開(公開日)

  • [ ] GTMコンテナを公開
  • [ ] 公開後すぐにプレビューモードで動作確認
  • [ ] 1時間後にGA4リアルタイムレポート確認
  • [ ] 異常があれば即座にロールバック

運用中の監視とメンテナンス

結論: 定期的な動作確認とメンテナンスにより、データ品質を長期的に維持できます。

GTMとdataLayerは「設定して終わり」ではなく、継続的な監視とメンテナンスが必要です。

定期的な動作確認:

日次チェック(所要時間:5分):

  • GA4のリアルタイムレポートでデータ流入を確認
  • 異常な数値(急増・急減)がないか確認
  • エラーログの確認(GTMのタグ発火失敗など)

週次チェック(所要時間:15分):

  • 主要イベントの発火数を前週と比較
  • コンバージョン数の推移を確認
  • GTMコンテナの変更履歴を確認(意図しない変更がないか)

月次チェック(所要時間:30分):

  • GTM設定の全体レビュー
  • 不要なタグ・トリガー・変数の削除
  • dataLayerの構造変更がないか確認
  • GA4のレポートで異常値を確認

Google Analytics 4のDebugViewの活用:

設定方法:

  1. GA4管理画面→「DebugView」を開く
  2. ブラウザにGA4 Debugger拡張機能をインストール
  3. 拡張機能をオンにして対象サイトにアクセス
  4. DebugViewに自分のアクセスがリアルタイム表示される

確認ポイント:

  • イベントが正しい順序で発火しているか
  • パラメータの値が正しいか
  • エラーイベント(_error)が発生していないか
  • 重複イベントが発生していないか

異常検知時の対応フロー:

1. 異常検知
   ↓
2. GTMプレビューモードで現象確認
   ↓
3. 原因の特定
   ├─ dataLayer側の問題
   ├─ GTM設定の問題
   └─ サイト側の仕様変更
   ↓
4. 対処方法の検討
   ├─ 緊急性が高い → 即座に修正・公開
   └─ 緊急性が低い → 次回定期メンテナンスで対応
   ↓
5. 修正実施・動作確認
   ↓
6. 記録・ドキュメント更新

メンテナンス記録の管理:

日付対応内容担当者影響範囲備考
2025/01/15purchase イベント修正田中全購入ページtransaction_id重複問題解決
2025/02/03新規タグ追加佐藤商品詳細ページview_item実装

ドキュメントの整備:

  • dataLayerの仕様書(変数名、値の範囲、出力タイミング)
  • GTMタグ一覧(タグ名、目的、トリガー条件)
  • 変更履歴(いつ、誰が、何を、なぜ変更したか)
  • トラブルシューティング履歴(過去の問題と解決方法)

よくある質問(FAQ)

Q1: dataLayer is not definedが解決しない場合は?

A: 以下の手順で段階的に確認してください。

まず、GTMスニペットとdataLayer初期化の順序を確認します。ページのソースコードを表示し、window.dataLayer = window.dataLayer || []; がGTMスニペットよりも上に記述されているか確認してください。もし下に配置されていれば、これが原因です。

次に、JavaScriptのエラーを確認します。ブラウザのコンソール(F12キー→Consoleタブ)を開き、他のJavaScriptエラーが発生していないか確認してください。他のエラーによってdataLayerの初期化が阻害されている可能性があります。

また、非同期読み込みになっていないかも確認してください。GTMスニペットやdataLayer初期化コードにasyncdefer属性が付いていると、読み込みタイミングが不確定になります。これらの属性を削除し、同期的に読み込まれるようにしてください。

キャッシュプラグインを使用している場合は、キャッシュをクリアしてから再度確認してください。古いキャッシュが残っていると、修正が反映されません。

それでも解決しない場合は、GTMのプレビューモードではなく、本番モードで動作しているか確認してください。プレビューモードでは正常でも、本番公開していないと実際のサイトでは動作しません。

最終手段として、GTMスニペット内に直接dataLayer初期化コードを含めることもできます:

<script>
  window.dataLayer = window.dataLayer || [];
  (function(w,d,s,l,i){w[l]=w[l]||[];...})(window,document,'script','dataLayer','GTM-XXXXXX');
</script>

Q2: プレビューでは動くが本番で動かない理由は?

A: 以下の4つの原因が考えられます。

1. GTMコンテナが公開されていない 最も多い原因です。GTM管理画面でワークスペースの変更を「保存」しただけでは本番環境には反映されません。右上の「送信」ボタンから明示的に公開する必要があります。バージョン履歴を確認し、最新の変更が公開済みになっているか確認してください。

2. 本番と検証で異なるコンテナIDを使用している プレビューモードでは検証用コンテナ(GTM-XXXXXXX)で動作確認し、本番サイトには本番用コンテナ(GTM-YYYYYYY)が設置されている場合、設定が反映されません。ページのソースコードを確認し、正しいコンテナIDが設置されているか確認してください。

3. ブラウザやCDNのキャッシュ問題 GTMのJavaScriptファイルがキャッシュされていると、古い設定のまま動作します。以下の方法でキャッシュをクリアしてください:

  • ブラウザのキャッシュクリア(Ctrl+Shift+Delete)
  • CDNのキャッシュパージ(CloudflareやAkamaiを使用している場合)
  • GTMプレビューURLに?gtm_debug=XXXXXパラメータを付けて強制再読み込み

4. 環境による条件分岐 タグやトリガーに環境判定の条件(URLやホスト名による分岐)が設定されていて、本番環境では条件に合致しないケースがあります。GTM管理画面でトリガーの条件を確認し、本番URLでも発火する設定になっているか確認してください。

確認手順:

  1. 本番URLでGTMプレビューモードを起動
  2. 「Tag Assistant Connected」と表示されるか確認
  3. 表示されない場合はコンテナIDまたは公開状態に問題あり
  4. 表示される場合はトリガー条件を確認

Q3: 複数のdataLayer.push()は同時に使える?

A: はい、複数のdataLayer.push()を連続して実行できますし、それが推奨される方法です。

dataLayerは配列なので、push()メソッドで次々とデータを追加していくことができます。各push()は独立して処理され、順番に配列に格納されます。

// ✅ 正しい - 複数のpushを連続実行
dataLayer.push({
  'pageCategory': 'blog',
  'pageType': 'article'
});

dataLayer.push({
  'event': 'pageLoaded',
  'timestamp': Date.now()
});

dataLayer.push({
  'user': {
    'id': '12345',
    'status': 'logged_in'
  }
});

ただし、eコマースイベントの場合は、前のecommerceデータをクリアしてから新しいデータをpushする必要があります:

// eコマースイベントの場合は先にクリア
dataLayer.push({ ecommerce: null });
dataLayer.push({
  'event': 'purchase',
  'ecommerce': { ... }
});

注意点:

  • 同じキー名で異なる値をpushすると、後から pushされた値が優先されます
  • イベント名(eventキー)は各push()で異なる名前にすべきです
  • データの順序は保証されますが、GTMタグの発火順序はトリガー設定に依存します

非推奨な方法:

// ❌ 避けるべき - 一度に大量のデータを詰め込む
dataLayer.push({
  'pageCategory': 'blog',
  'pageType': 'article',
  'event': 'pageLoaded',
  'timestamp': Date.now(),
  'user': {
    'id': '12345'
  },
  'product': { ... },
  'ecommerce': { ... }
});

関心の分離という観点から、ページ情報、ユーザー情報、eコマース情報は別々にpushすることを推奨します。

Q4: GTMとGoogleアナリティクスどちらの問題か見分ける方法は?

A: 以下の手順で段階的に切り分けられます。

ステップ1: GTMプレビューモードで確認

まずGTMプレビューモードを起動し、タグが発火しているか確認します:

  • 「Tags Fired」に該当タグが表示されている → GTM側は正常、GA4側の問題
  • 「Tags Not Fired」に表示されている → GTM側の問題(トリガー設定など)

ステップ2: ネットワークタブで確認

ブラウザのデベロッパーツール(F12)→「Network」タブを開き、以下を確認します:

確認項目正常異常
GTMのリクエストwww.googletagmanager.com/gtm.js が200で返る404や403エラー
GA4のリクエストwww.google-analytics.com/g/collect が200で返るリクエスト自体がない
ペイロードmeasurement_idとイベントデータが含まれるデータが空または不正

ステップ3: GA Debugger拡張機能で確認

GA Debugger拡張機能をオンにし、ブラウザコンソールを確認します:

  • コンソールにGA4のイベント詳細が表示される → GTMからGA4への送信は成功
  • 何も表示されない → GTMタグの設定に問題あり

ステップ4: GA4のDebugViewで確認

GA4の管理画面→DebugViewを開き:

  • イベントが表示される → GA4側で正常に受信、問題なし
  • イベントが表示されない → 測定ID間違いまたはフィルター設定の問題

問題箇所の判定フローチャート:

GTMプレビューでタグ発火している?
├─ NO → GTM側の問題
│  └─ トリガー設定、タグ設定を確認
└─ YES
    ↓
    Networkタブでga4リクエストが飛んでいる?
    ├─ NO → GTMタグ設定の問題
    │  └─ 測定IDが間違っている可能性
    └─ YES
        ↓
        GA4 DebugViewにイベント表示される?
        ├─ NO → GA4側の問題
        │  └─ フィルター設定、測定ID確認
        └─ YES → 正常動作

よくある問題と見分け方:

症状問題箇所確認方法
GTMプレビューで「Tags Not Fired」GTM(トリガー)トリガー条件を確認
プレビューで発火するがNetworkにリクエストなしGTM(タグ設定)測定IDを確認
Networkにリクエストあるがレスポンス400GA4パラメータ形式を確認
DebugViewに表示されないGA4(フィルター)IPフィルター設定確認

Q5: データレイヤー変数が空配列で返ってくる原因は?

A: 空配列が返ってくる原因は主に3つあります。

原因1: タイミング問題

dataLayer.push()が実行される前にGTMが変数を取得しようとしている場合、空配列が返ってきます。

確認方法:

// ブラウザコンソールで確認
console.log(dataLayer);
// 結果: [] ← 空配列の場合は値がpushされていない

対処法:

  • GTMのトリガータイプを「Page View」から「DOM Ready」または「Window Loaded」に変更
  • カスタムイベントをdataLayer.push()した後に発行し、そのイベントをトリガーにする
// カスタムイベント方式
dataLayer.push({
  'productId': 'P12345',
  'productName': 'サンプル商品'
});
dataLayer.push({
  'event': 'productDataReady'  // このイベントをトリガーに使う
});

原因2: 変数名の指定ミス

GTM側で設定したデータレイヤー変数名が、実際のdataLayerのキー名と一致していない場合も空配列になります。

確認方法:

// 実際のdataLayerの中身を確認
console.log(dataLayer[dataLayer.length - 1]);
// 例: {productId: "P12345", productName: "サンプル商品"}

// GTM側で設定している変数名が "product_id" の場合、
// キー名が一致しないため取得できない

対処法:

  • ブラウザコンソールで実際のキー名を確認
  • GTM変数設定で完全に一致するキー名を指定
  • 大文字小文字、アンダースコア、ハイフンの違いに注意

原因3: 配列そのものを取得しようとしている

dataLayer全体(配列)を取得しようとすると、空配列が返ってくることがあります。

間違った設定:

GTM変数設定:
変数タイプ: データレイヤー変数
データレイヤー変数名: (空欄) ← これはNG

正しい設定:

GTM変数設定:
変数タイプ: データレイヤー変数
データレイヤー変数名: productId ← 具体的なキー名を指定

デバッグ手順:

  1. GTMプレビューモードを起動
  2. 対象ページでイベントを発火させる
  3. 「Variables」タブを開く
  4. 問題の変数の値を確認:
    • undefined → キー名の不一致またはタイミング問題
    • [](空配列) → 配列自体を取得しようとしている
    • 正しい値 → 問題なし
  5. 「Data Layer」タブで実際のdataLayerを確認
  6. キー名が完全一致しているか確認

確認用コード(コンソールで実行):

// 最新のdataLayerオブジェクトを取得
let latest = dataLayer[dataLayer.length - 1];
console.log('最新のdataLayer:', latest);

// 特定のキーの値を確認
console.log('productIdの値:', latest.productId);

// GTM変数で指定している名前で取得できるか確認
let testValue = dataLayer.filter(obj => obj.productId)[0];
console.log('フィルター結果:', testValue);

まとめ

GTMのデータレイヤーエラーは、「定義の問題」「タイミングの問題」「名前・構造の不一致」「GTM側設定ミス」の4つに大別されます。

エラー原因の早見表:

エラー症状原因対処法
dataLayer is not defined初期化がGTMより後GTMより前にdataLayerを初期化
変数がundefinedタイミング問題トリガータイプをDOM Readyに変更
変数がundefinedキー名の不一致コンソールで実際のキー名を確認
タグが発火しない未公開GTMコンテナを公開
タグが発火しないトリガー条件不一致プレビューでイベント名を確認
eコマースデータが送信されない構造違いGA4形式に修正、必須フィールド確認

解決できない場合の相談先:

この記事で解説した方法を実践することで、データレイヤーエラーの大部分は自力で解決できるはずです。正確なデータ収集環境を構築し、効果的なWeb分析を実現しましょう。

ブログ一覧に戻る

ご相談はこちら