dataLayer: как работает и как использовать
dataLayer — глобальный массив между сайтом и GTM. Как устроен, как правильно пушить события, читать значения через переменные и избегать типичных ошибок.
Содержание
dataLayer — глобальный JavaScript-массив на странице, через который сайт передаёт структурированные данные в Google Tag Manager. GTM слушает этот массив и, когда видит нужное событие, активирует теги. Без dataLayer трекинг опирается на хрупкий DOM — изменили класс кнопки и всё сломалось.
Эта статья — практический разбор: как устроен dataLayer, как правильно пушить события, как читать значения в GTM, реальные примеры для e-commerce и кастомных user properties, порядок инициализации и типичные ошибки.
Материал является продолжением основ GTM — если вы ещё не разобрались с тегами и триггерами, сначала прочитайте тот посибник.
Что такое dataLayer и зачем он нужен
GTM может извлекать данные двумя способами: из DOM (класс элемента, текст кнопки, значение поля) или из dataLayer. DOM-подход ненадёжен: любой редизайн ломает трекинг. dataLayer — это контракт между командами разработки и аналитики: разработчик пушит чётко описанные объекты, аналитик читает их через GTM независимо от вёрстки.
Смотрите разницу на примере трекинга клика «Купить»:
| Подход | Настройка | Что случится при редизайне |
|---|---|---|
| DOM (Click trigger на CSS класс) | Trigger: .btn-buy | Разработчик переименовал класс — трекинг молчит |
| dataLayer.push | event: 'add_to_cart' в onClick | Кнопка изменила вид — push остался, всё ок |
Отдельный плюс: через DOM никогда не получишь данные, которых нет на странице — цену из бекенда, ID авторизованного пользователя, статус заказа. dataLayer позволяет передать всё это из серверного шаблона или клиентского JS.
Если хотите разобраться в термине подробнее — смотрите glossary: dataLayer.
Структура dataLayer
window.dataLayer — обычный массив JavaScript. Каждый элемент — объект с произвольными ключами и обязательным полем event (если хотите тригернуть GTM).
window.dataLayer = [
// Объект 0 — контекст страницы (без event, просто данные)
{
pageType: "product",
pageLanguage: "ru",
userId: "u_8821"
},
// Объект 1 — событие при загрузке
{
event: "page_view_ready",
pageTitle: "Кроссовки Nike Air Max"
}
];
GTM при старте обрабатывает весь массив сверху вниз. Если находит объект с полем event — проверяет Custom Event триггеры с таким именем. Если объект без event — просто обновляет внутреннее состояние переменных.
Ключевые поля
event(string) — имя события, которое GTM будет матчить по Custom Event триггерам. Называйте snake_case:add_to_cart,form_submit,video_play.- Любые другие поля — это параметры события, которые вы читаете через Data Layer Variable.
Инициализация dataLayer: порядок важен
Одна из самых распространённых ошибок — неправильный порядок скриптов. Правило простое: dataLayer должен быть объявлен до сниппета GTM.
Структура <head> должна выглядеть так:
<head>
<!-- 1. Сначала инициализация dataLayer и первый push -->
<script>
window.dataLayer = window.dataLayer || [];
// Контекст страницы, известный в момент рендера (серверные данные)
window.dataLayer.push({
pageType: "product",
userId: "u_8821", // если есть авторизованный пользователь
userType: "returning"
});
</script>
<!-- 2. Потом сниппет GTM -->
<script>
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});...
</script>
</head>
Почему window.dataLayer = window.dataLayer || []? Защита от двойной загрузки фрагмента (SPA-навигация, ошибки сборки). Если просто window.dataLayer = [] — вы каждый раз стираете накопленные данные.
Если контекст страницы придёт после GTM, он всё равно попадёт в массив, но GTM уже обработает первый Page View без этих данных. Тегам, привязанным к pageview, эти переменные будут недоступны.
dataLayer.push: как правильно отправлять события
dataLayer.push(obj) — основной метод. Вызывайте его в любой момент после инициализации:
// При клике на кнопку (ваш JS)
document.querySelector('#btn-add-to-cart').addEventListener('click', function() {
dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: 'RUB',
value: 4990,
items: [{
item_id: 'SKU_1234',
item_name: 'Кроссовки Nike Air Max',
item_category: 'Обувь',
price: 4990,
quantity: 1
}]
}
});
});
GTM получает этот push, находит Custom Event триггер с именем add_to_cart, активирует GA4 Event тег — и событие летит в аналитику.
Важный нюанс: очистка ecommerce
Google требует очищать предыдущий ecommerce-объект перед каждым новым пушем. Если вы пушите add_to_cart после view_item, GTM смержит оба объекта — и во втором событии появятся поля первого.
Правило: перед любым ecommerce-пушем всегда делайте:
dataLayer.push({ ecommerce: null }); // очистить предыдущее состояние
dataLayer.push({
event: 'add_to_cart',
ecommerce: { ... }
});
Это официальная рекомендация Google в документации GA4 ecommerce (Make ecommerce measurements with Tag Manager).
Чтение dataLayer в GTM через Data Layer Variable
Чтобы использовать значение из dataLayer в тегах или триггерах — создайте переменную типа Data Layer Variable.
Путь: Variables → User-Defined Variables → New → Variable Type → Data Layer Variable.
Базовые настройки
- Variable Name — ключ или путь к вложенному значению через точку.
- Data Layer Version — всегда версия 2 (по умолчанию). Версия 1 — legacy, не поддерживает пути через точку (например,
ecommerce.value).
Примеры Variable Name для разных структур:
Простая пара ключ-значение:
Variable Name: pageType
Значение из push: { pageType: "product" } → вернёт "product"
Вложенный объект (через точку):
Variable Name: ecommerce.value
Значение из push: { ecommerce: { value: 4990 } } → вернёт 4990
Первый элемент массива:
Variable Name: ecommerce.items.0.item_name
Значение из push: { ecommerce: { items: [{ item_name: "Кроссовки" }] } } → "Кроссовки"
Использование переменной в теге GA4
После создания переменной её можно использовать в GA4 Event Tag как параметр:
Tag: GA4 Event
Event Name: add_to_cart
Event Parameters:
currency → {{DL - ecommerce.currency}}
value → {{DL - ecommerce.value}}
items → {{DL - ecommerce.items}}
Префикс DL - в названии — рекомендованная конвенция для удобства чтения в GTM.
Примеры: ecommerce events для GA4
Ниже — полные примеры пушей для основных ecommerce-событий GA4. Структура items[] стандартизирована Google.
view_item — просмотр карточки товара
dataLayer.push({ ecommerce: null });
dataLayer.push({
event: 'view_item',
ecommerce: {
currency: 'RUB',
value: 4990,
items: [{
item_id: 'SKU_1234',
item_name: 'Кроссовки Nike Air Max',
item_brand: 'Nike',
item_category: 'Обувь',
item_category2: 'Кроссовки',
price: 4990,
quantity: 1
}]
}
});
purchase — завершение покупки
Обычно отправляется на thank-you-page, где бекенд уже знает детали заказа:
dataLayer.push({ ecommerce: null });
dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'ORDER_88210', // обязательно, уникальный
currency: 'RUB',
value: 9980, // без доставки и налогов
shipping: 290,
tax: 0,
coupon: 'SALE10', // если применялся
items: [
{
item_id: 'SKU_1234',
item_name: 'Кроссовки Nike Air Max',
price: 4990,
quantity: 2
}
]
}
});
Важно: transaction_id должен быть уникальным. GA4 дедуплицирует повторные отправки по transaction_id — дубликаты purchase с одним ID игнорируются.
begin_checkout — начало оформления заказа
dataLayer.push({ ecommerce: null });
dataLayer.push({
event: 'begin_checkout',
ecommerce: {
currency: 'RUB',
value: 9980,
items: [
{ item_id: 'SKU_1234', item_name: 'Кроссовки Nike Air Max', price: 4990, quantity: 2 }
]
}
});
Примеры: user properties через dataLayer
Помимо ecommerce, dataLayer — удобный канал для передачи атрибутов пользователя, которые нужны в GTM для сегментации или персонализации.
Обычно эти данные устанавливаются при загрузке страницы — если есть авторизация:
// Серверный шаблон (PHP, Python и т.д.) рендерит это в <head>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
userId: "u_8821", // не Email и не PII, только хешированный/внутренний ID
userType: "returning", // new / returning
userPlan: "pro", // free / pro / enterprise
userCountry: "RU"
});
В GTM создайте Data Layer Variables: userId, userType, userPlan. Затем используйте их в GA4 Configuration Tag → User Properties:
user_id → {{DL - userId}}
user_type → {{DL - userType}}
plan → {{DL - userPlan}}
Важно про PII: не передавайте Email, имя, телефон через dataLayer напрямую — это нарушает условия Google Analytics и GDPR. Только анонимизированные ID или категориальные атрибуты.
Как отлаживать dataLayer в Preview Mode
GTM Preview Mode — главный инструмент проверки. Откройте Preview, выполните нужное действие на сайте, затем в Tag Assistant:
- Выберите событие слева (например,
add_to_cart). - Вкладка Variables — показывает значения всех Data Layer Variables на момент события.
- Вкладка Data Layer — показывает полное состояние массива после каждого пуша.
- Вкладка Tags — показывает какие теги сработали или нет.
Если в Variables видите undefined — значение либо не пришло, либо путь написан неправильно.
Также удобно прямо в консоли браузера просмотреть текущее состояние:
// Показать весь массив
console.log(window.dataLayer);
// Показать последний push
console.log(window.dataLayer[window.dataLayer.length - 1]);
Типичные ошибки при работе с dataLayer
1. Инициализация после сниппета GTM
GTM стартовал, запустил первый Page View — а dataLayer с контекстом ещё не пришёл. Исправление: всегда window.dataLayer = window.dataLayer || [] и первый push до GTM сниппета.
2. Нет очистки ecommerce перед пушем
Без dataLayer.push({ ecommerce: null }) поля от предыдущего события остаются в состоянии. В purchase появятся items от view_item. Делайте очистку перед каждым ecommerce пушем.
3. Ошибка в названии ключа или регистре
GTM чувствителен к регистру: UserID и userId — разные ключи. Проверяйте Variable Name с точностью до символа.
4. Версия Data Layer Variable = 1
В GTM при создании Data Layer Variable есть выбор Version 1 или 2. Версия 1 — устаревшая, не поддерживает пути через точку (например, ecommerce.value). Всегда выбирайте версию 2.
5. Двойная отправка событий
Происходит при SPA-навигации (React, Vue): при переходах между страницами компонент может рендериться дважды или push вызывается из useEffect с некорректными зависимостями. Смотрите GA4 DebugView — если событие приходит дважды подряд с разницей <1с — это оно.
6. Передача PII
Email или телефон в dataLayer → в GA4 → в Google — прямое нарушение условий обслуживания и GDPR. Вместо email — SHA-256 хеш или внутренний CRM-ID.
7. Push до того, как страница загрузила JS-файл с логикой
В SPA при client-side навигации код компонента может запустить dataLayer.push до того, как GTM загрузил текущий контейнер (если используете lazy route). Решение — проверять window.google_tag_manager или использовать window.dataLayer.push с eventCallback.
8. Ненадёжные имена событий
Названия типа buttonClick, formsubmit, AddToCart (camelCase или без правил) усложняют поддержку. Стандарт GA4 — snake_case, в нижнем регистре: form_submit, add_to_cart, video_start. Придерживайтесь этого с первого дня.
Как связаны dataLayer, GTM и GA4
Для лучшего понимания — общая схема потока данных:
Действие пользователя (клик/переход/покупка)
↓
dataLayer.push({ event: 'purchase', ecommerce: {...} })
↓
GTM слышит новое событие в массиве
↓
GTM находит Custom Event триггер "purchase"
↓
GTM активирует GA4 Event тег
↓
Тег читает параметры из Data Layer Variables:
{{DL - ecommerce.value}} → 9980
{{DL - ecommerce.items}} → [...]
↓
GA4 получает событие purchase с параметрами
dataLayer — посредник. Сайт не знает, что существует GA4 или GTM; GTM не знает, что произошло на сайте. dataLayer — нейтральный протокол между ними. Если завтра вы меняете GA4 на Matomo или добавляете Meta Pixel — просто подключаете новый тег в GTM, пуши сайта не меняются.
Подробнее о событиях в аналитике — в глоссарии.
Контрольный список перед публикацией новых пушей
Перед тем как мёрджить код с новыми dataLayer пушами, пройдитесь по чек-листу:
-
window.dataLayer = window.dataLayer || []стоит до сниппета GTM. - Перед ecommerce пушем есть
dataLayer.push({ ecommerce: null }). -
eventназван вsnake_case. - Вложенные поля (
ecommerce.currency,ecommerce.value) соответствуют GA4-схеме. - Никаких PII в открытом виде.
- Проверено в GTM Preview Mode — нужные теги сработали.
- Проверено в GA4 DebugView — событие появилось с правильными параметрами.
- Отсутствуют дубликаты (особенно для SPA).
Связанные материалы
- GTM: основы работы с тегами, триггерами и переменными — с чего начинать с GTM.
- Glossary: dataLayer — определение и краткий справочник.
- Glossary: Event — что такое событие в контексте GA4 и GTM.
Похожие статьи
dataLayer (уровень данных): полное руководство — как работает в GTM, push, e-commerce, SPA
Что такое dataLayer в Google Tag Manager, как работает уровень данных, формат push-событий, разница с gtag.js, паттерны для e-commerce, SPA, server-side, типичные ошибки.
GtmКак настроить событие в GTM: тег и триггер
Пошаговая инструкция: настроить кастомный тег и триггер в GTM для отслеживания клика по кнопке — dataLayer.push, Custom Event trigger, GA4 event. Проверка через Preview.
GtmGoogle Tag Manager: что это и как настроить теги
Полное руководство по Google Tag Manager для начинающих: что такое GTM, как установить, как работают теги/триггеры/переменные, dataLayer, Preview Mode, server-side GTM и Consent Mode v2.