GTMデータレイヤーの使い方|5分で理解できる設定手順とサンプルコード集
GTMデータレイヤーを使えば、通常のGA4では取得できない詳細なユーザー行動データを90%以上の精度で取得可能です。**本記事では、コピペで使える実装コード15選と実際の設定手順を画像付きで解説します。
2025年現在、Webマーケティングにおいてユーザー行動の詳細な分析は必須となっています。本記事を読むことで、自社のKPIに完全に合致したデータ収集システムを構築できるようになります。

結論、データレイヤーは通常計測することができないデータを計測するためのツールです。
目次
GTMデータレイヤーとは?基礎知識を3分で理解
データレイヤーの定義
GTM(Google Tag Manager)のデータレイヤーとは、Webサイト上で発生するイベントやユーザー情報を一時的に保存する「データの受け皿」です。
簡単に例えると、データレイヤーは「郵便局の仕分け係」のような役割を果たします。
- 通常の場合: サイト → 直接GA4に送信(限定的なデータのみ)
- データレイヤー使用: サイト → データレイヤーで整理 → GA4に詳細データを送信
なぜ重要なのか?
標準のGA4設定では取得できないデータ例
- ユーザーの会員ランク
- 商品カテゴリーの詳細情報
- フォーム入力の段階別離脱率
- カスタマイズされたユーザー行動パターン
これらのデータを取得することで、売上向上に直結する具体的な改善点を発見できます。
データレイヤーが必要な5つのケース
ケース1: ECサイトの詳細な購買分析
取得したいデータ: 商品カテゴリー別の購入率、ユーザーランク別の購買行動
効果:商品レコメンドの精度向上、売上20-30%アップ
ケース2: BtoBサイトのリード品質分析
取得したいデータ:資料ダウンロード前の行動履歴、フォーム入力時間
効果:質の高いリードの特定、営業効率の向上
ケース3: メディアサイトのコンテンツ分析
取得したいデータ:記事読了率、スクロール深度、関連記事クリック率
効果:コンテンツ制作の方向性最適化、PV数向上
ケース4: アプリダウンロードサイトの最適化
取得したいデータ:ダウンロードボタンまでの導線、離脱ポイント
効果:コンバージョン率の改善
ケース5: 複数マーケティングツールでのデータ統合
取得したいデータ:統一されたユーザーID、行動データ
効果:マーケティングROIの正確な測定
データレイヤーの基本構造
基本的なコードの記述方法と設定方法が決まっております。これに沿って設定する必要があり、エラーになると収集することができません。コードの記述が必要になりますが、ChatGTPなどを駆使すれば、コードの理解がなくても設定できるものはあります。
データレイヤーの実装方法
データレイヤーは下記のコードがベースになります。このベースに沿って取得したい条件や方法などをJavaScriptで記述していくことになります。
データレイヤーのコードの中の { } の括弧の中に必要なデータを記述します。
具体的な記述方法は別のセクションでご紹介します。
<script>
dataLayer = [];
dataLayer.push({
//ここの処理を記述
});
</script>
基本的なデータ構造
- イベント名
- イベントカテゴリ
- イベントアクション
- イベントラベル
- カスタムデータ
基本のデータ構造のデータレイヤーのコード例
コード自体の細かい解説は割愛しますが、基本的な記述方法になりますので、取得したいデータなどによって変わってきます。
// データレイヤーの初期化
<script>
// グローバルのデータレイヤー配列を初期化 決まりのようなもの
dataLayer = [];
// 基本的なイベントデータの追加例
dataLayer.push({
'event': 'button_click', // イベント名
'eventCategory': 'CTA', // イベントカテゴリ
'eventAction': 'click', // イベントアクション
'eventLabel': 'sign_up_button', // イベントラベル
'customData': { // カスタムデータ
'userId': 'user123',
'userType': 'new_visitor',
'pageSection': 'hero_section'
}
});
上記のコードで「ボタンクリックの計測」をすることができます。
次でイベントトラッキングの設定方法を詳しく紹介します。
コピペで使える実装コード15選
【必須レベル】基本的なイベント計測
ボタンクリック計測(汎用版)
実装目的: 重要なCTAボタンのクリック率測定
設定難易度: ★☆☆ 所要時間: 5分
// HTML: ボタンにdata属性を追加
<button data-gtm-button="cta_main" class="contact-btn">お問い合わせ</button>
// JavaScript: クリックイベントの設定
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('[data-gtm-button]').forEach(function(button) {
button.addEventListener('click', function() {
dataLayer.push({
'event': 'button_click',
'eventCategory': 'CTA',
'eventAction': 'click',
'eventLabel': this.getAttribute('data-gtm-button'),
'buttonText': this.textContent,
'pageUrl': window.location.href
});
});
});
});
フォーム分析(完全版)
実装目的: フォーム最適化のためのデータ収集
設定難易度: ★★☆ 所要時間: 15分
// フォーム入力開始の検知
document.addEventListener('DOMContentLoaded', function() {
const forms = document.querySelectorAll('form[data-gtm-form]');
forms.forEach(function(form) {
let hasStarted = false;
const formName = form.getAttribute('data-gtm-form');
// 入力開始の検知
form.addEventListener('input', function() {
if (!hasStarted) {
dataLayer.push({
'event': 'form_start',
'eventCategory': 'Form',
'eventAction': 'start',
'eventLabel': formName,
'formName': formName,
'timestamp': new Date().toISOString()
});
hasStarted = true;
}
});
// 送信完了の検知
form.addEventListener('submit', function() {
dataLayer.push({
'event': 'form_submit',
'eventCategory': 'Form',
'eventAction': 'submit',
'eventLabel': formName,
'formName': formName,
'timestamp': new Date().toISOString()
});
});
});
});
4-3. eコマース購入完了計測
実装目的: 売上データの詳細分析
設定難易度: ★★★ 所要時間: 20分
// 購入完了ページでの実装
dataLayer.push({
'event': 'purchase',
'ecommerce': {
'transaction_id': 'ORDER-123456',
'value': 15.25,
'currency': 'JPY',
'items': [{
'item_id': 'SKU123',
'item_name': '商品名',
'category': 'カテゴリー',
'quantity': 1,
'price': 15.25
}]
},
'user_data': {
'customer_type': 'returning', // new or returning
'user_id': 'USER123'
}
});
【推奨レベル】行動分析系
スクロール深度計測
実装目的: コンテンツエンゲージメント分析
設定難易度: ★★☆ 所要時間: 10分
// スクロール深度の計測
let scrollDepthMarks = [25, 50, 75, 90];
let scrollDepthTriggered = [];
window.addEventListener('scroll', function() {
const scrollPercent = Math.round((window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100);
scrollDepthMarks.forEach(function(mark) {
if (scrollPercent >= mark && !scrollDepthTriggered.includes(mark)) {
scrollDepthTriggered.push(mark);
dataLayer.push({
'event': 'scroll_depth',
'eventCategory': 'Engagement',
'eventAction': 'scroll',
'eventLabel': mark + '%',
'scrollDepth': mark,
'pageUrl': window.location.href
});
}
});
});
ファイルダウンロード計測
実装目的: 資料ダウンロードの効果測定
設定難易度: ★☆☆ 所要時間: 5分
// ダウンロードリンクの計測
document.addEventListener('DOMContentLoaded', function() {
const downloadLinks = document.querySelectorAll('a[href$=".pdf"], a[href$=".zip"], a[href$=".doc"], a[href$=".docx"]');
downloadLinks.forEach(function(link) {
link.addEventListener('click', function() {
const fileName = this.href.split('/').pop();
const fileExtension = fileName.split('.').pop();
dataLayer.push({
'event': 'file_download',
'eventCategory': 'Download',
'eventAction': 'click',
'eventLabel': fileName,
'fileType': fileExtension,
'fileName': fileName,
'downloadUrl': this.href
});
});
});
});
外部リンククリック計測
実装目的: 外部サイトへの誘導効果測定
設定難易度: ★☆☆ 所要時間: 5分
// 外部リンクの計測
document.addEventListener('DOMContentLoaded', function() {
const currentDomain = window.location.hostname;
const externalLinks = document.querySelectorAll('a[href^="http"]');
externalLinks.forEach(function(link) {
const linkDomain = new URL(link.href).hostname;
if (linkDomain !== currentDomain) {
link.addEventListener('click', function() {
dataLayer.push({
'event': 'external_link_click',
'eventCategory': 'External Link',
'eventAction': 'click',
'eventLabel': linkDomain,
'externalUrl': this.href,
'linkText': this.textContent || this.title || 'No text'
});
});
}
});
});
【上級レベル】カスタム分析
動画再生計測
実装目的: 動画コンテンツのエンゲージメント分析
設定難易度: ★★★ 所要時間: 15分
// YouTube埋め込み動画の計測
document.addEventListener('DOMContentLoaded', function() {
const videos = document.querySelectorAll('video, iframe[src*="youtube"]');
videos.forEach(function(video, index) {
if (video.tagName === 'VIDEO') {
// HTML5 video
video.addEventListener('play', function() {
dataLayer.push({
'event': 'video_play',
'eventCategory': 'Video',
'eventAction': 'play',
'eventLabel': 'Video ' + (index + 1),
'videoTitle': this.title || 'Untitled Video',
'videoDuration': this.duration
});
});
video.addEventListener('ended', function() {
dataLayer.push({
'event': 'video_complete',
'eventCategory': 'Video',
'eventAction': 'complete',
'eventLabel': 'Video ' + (index + 1),
'videoTitle': this.title || 'Untitled Video'
});
});
}
});
});
サイト内検索計測
実装目的: 検索機能の利用状況分析
設定難易度: ★★☆ 所要時間: 10分
// サイト内検索の計測
document.addEventListener('DOMContentLoaded', function() {
const searchForms = document.querySelectorAll('form[data-gtm-search], .search-form');
searchForms.forEach(function(form) {
form.addEventListener('submit', function(e) {
const searchInput = this.querySelector('input[type="search"], input[name*="search"], input[name*="q"]');
const searchTerm = searchInput ? searchInput.value : '';
if (searchTerm) {
dataLayer.push({
'event': 'site_search',
'eventCategory': 'Search',
'eventAction': 'submit',
'eventLabel': searchTerm,
'searchTerm': searchTerm,
'searchResults': document.querySelectorAll('.search-result, .result-item').length || 0
});
}
});
});
});
エラーページ計測
実装目的: サイトエラーの監視と改善
設定難易度: ★☆☆ 所要時間: 5分
// 404エラーページの計測
if (document.title.includes('404') || window.location.pathname.includes('404')) {
dataLayer.push({
'event': 'error_page',
'eventCategory': 'Error',
'eventAction': '404',
'eventLabel': window.location.pathname,
'errorPage': window.location.href,
'referrer': document.referrer || 'Direct'
});
}
// JavaScriptエラーの計測
window.addEventListener('error', function(e) {
dataLayer.push({
'event': 'javascript_error',
'eventCategory': 'Error',
'eventAction': 'JavaScript Error',
'eventLabel': e.message,
'errorMessage': e.message,
'errorFile': e.filename,
'errorLine': e.lineno
});
});
4-10. カスタムユーザー属性計測
実装目的: ユーザーセグメント別の行動分析
設定難易度: ★★★ 所要時間: 20分
// ユーザー属性の設定(ログイン後等で実行)
function setUserAttributes(userData) {
dataLayer.push({
'event': 'user_attributes_set',
'user_id': userData.userId || 'anonymous',
'user_type': userData.userType || 'guest', // guest, member, premium
'membership_level': userData.membershipLevel || 'none',
'registration_date': userData.registrationDate || null,
'last_purchase_date': userData.lastPurchaseDate || null,
'total_purchase_amount': userData.totalPurchaseAmount || 0,
'preferred_category': userData.preferredCategory || 'unknown'
});
}
// 使用例
// setUserAttributes({
// userId: 'user123',
// userType: 'premium',
// membershipLevel: 'gold',
// totalPurchaseAmount: 50000
// });
その他の実装例(5選)
タイマー計測(滞在時間)
let timeOnPage = 0;
const timer = setInterval(function() {
timeOnPage += 10;
if (timeOnPage % 60 === 0) { // 1分ごと
dataLayer.push({
'event': 'time_on_page',
'eventCategory': 'Engagement',
'eventAction': 'time_milestone',
'eventLabel': (timeOnPage / 60) + ' minutes',
'timeOnPage': timeOnPage
});
}
}, 10000); // 10秒ごとにチェック
クリックヒートマップ
document.addEventListener('click', function(e) {
const element = e.target;
const rect = element.getBoundingClientRect();
dataLayer.push({
'event': 'click_heatmap',
'eventCategory': 'Heatmap',
'eventAction': 'click',
'eventLabel': element.tagName + '.' + element.className,
'clickX': e.clientX,
'clickY': e.clientY,
'elementType': element.tagName,
'elementClass': element.className
});
});
カートアクション計測
// カートに追加
function trackAddToCart(productData) {
dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {
'currency': 'JPY',
'value': productData.price,
'items': [{
'item_id': productData.id,
'item_name': productData.name,
'category': productData.category,
'quantity': productData.quantity,
'price': productData.price
}]
}
});
}
A/Bテスト計測
// A/Bテストバリエーションの記録
dataLayer.push({
'event': 'ab_test_view',
'eventCategory': 'AB Test',
'eventAction': 'view',
'eventLabel': 'test_name_variation_A',
'abTestName': 'button_color_test',
'abTestVariation': 'red_button',
'abTestId': 'test_001'
});
コンバージョンファネル計測
// ファネルステップの計測
function trackFunnelStep(stepName, stepNumber) {
dataLayer.push({
'event': 'funnel_step',
'eventCategory': 'Funnel',
'eventAction': 'step_' + stepNumber,
'eventLabel': stepName,
'funnelStep': stepNumber,
'funnelName': 'purchase_funnel'
});
}
// 使用例
// trackFunnelStep('product_view', 1);
// trackFunnelStep('add_to_cart', 2);
// trackFunnelStep('checkout_start', 3);
GTMのデータレイヤーのベストプラクティス
命名規則
命名規則は最も重要になります。命名規則が決まってない場合は、決めるようにしてください。
サイトを運用している期間が短い場合や立ち上げたばかりサイトでは、どのような名前でも問題ないですが、サイト運用期間が長くなると、ページ数も増えてくるとともに計測するべきデータ量も必然的に多くなります。
その際に、GTMで独自でイベントを作成したりすることが必ずあります。GTM上にイベントが増えすぎて動いているかどうかわからないタグなども発生するため必ず初期の段階で命名規則はつけるようにしてください。
- 一貫性のある命名
- 運用保守がしやすい
- 重複や複数計測の回避
- 管理コストの削減
パフォーマンスの最適化
命名規則を決めておくとどのタイミングで取得するデータか判断がつくため、不要な計測や正しい順番で計測することもできるため結果的にパフォーマンスも良くなることがあります。
- 必要最小限のデータ送信
- 適切なイベントのタイミング
- エラー処理の実装
一般的なGTMで計測するべき箇所
下記の例は一般的なものになるため、自社で管理・KPIとして設定しているデータを計測するようにしてください。取得しすぎないようにしてください。データを取得することがたまに目的になっていることもありますので、明確なビジネスの目的に対して重要な指標のデータを取得してください。
フォーム分析
- 入力開始
- 入力完了
- エラー発生
- 送信完了
ユーザー行動分析
- スクロール深度
- 滞在時間
- クリック位置
- 離脱タイミング
データレイヤーを設定してよくあるトラブル
よくある問題と解決方法
- イベントが発火しない
- データが正しく送信されない
- 二重カウント
- タイミングの問題
特に多いのがイベントが発火しない。というトラブルになります。この場合は、設定が間違っていることが多いため見直すことで基本的には動くはずです。
しかし、何点か動かない場合もございます。
サイトの仕様上の問題で、ボタンのクラス名などがサイトを表示させたタイミングで変更される仕様のサイトや外部のツールの計測などを行う際に計測ができない原因になっていることがあります。
この仕様にサイトがなっている場合は、データレイヤーでの取得方法を変更する必要があります。
また、サイトが長い間運用されており、複数のデータレイヤーがある場合やリニュアールや一部ページの改修を行うと計測ができないデータが発生することもありますのでご注意ください。
チェックポイント
- コードの記述位置
- イベントの順序
- 変数の定義
- トリガーの設定
- サイトの取得要素の確認
まとめ:GTMデータレイヤーの重要性
GTMのデータレイヤーは、Webサイトの分析に必要不可欠なツールです。適切に設定することで、より詳細なデータ収集と分析が可能になります。本記事で解説した内容を参考に、自社のWebサイトに最適な実装を行ってください。
- より正確なユーザー行動の把握
- KPIに基づいた的確なデータ収集
- マーケティング施策の効果測定の精度向上
上記の実装方法や注意点を参考に、自社のWebサイトに最適なデータレイヤーの設定を行ってください。
[技術用語集]
- Google Tag Manager (GTM)
Webサイトにタグを追加・管理するためのタグ管理システム。 - データレイヤー
Webサイト上のデータを一時的に保存する仮想的なデータ層。 - イベント
ユーザーの行動や特定のアクションを示すデータポイント。 - トリガー
タグを実行する条件を定義する設定項目。 - タグ
Webサイトに追加する tracking code や解析用のスクリプト。 - カスタムイベント
標準のイベント以外に、独自に定義したイベント。