Настройка Google Tag Manager на 1С-Битрикс
GTM — прослойка между сайтом и аналитикой. Вместо того чтобы каждый раз просить разработчика добавлять пиксели и коды отслеживания, маркетолог настраивает триггеры и теги в интерфейсе GTM сам. Но чтобы это работало, разработчику нужно один раз правильно установить GTM и настроить dataLayer с событиями электронной торговли.
Установка GTM в шаблон Битрикс
GTM требует два фрагмента кода: один в <head>, второй сразу после <body>. В шаблоне Битрикс (/bitrix/templates/[name]/header.php):
<?php
// ID контейнера GTM из аккаунта Google Tag Manager
$gtmId = \Bitrix\Main\Config\Option::get('custom', 'gtm_container_id', 'GTM-XXXXXXX');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- GTM в head (как можно раньше) -->
<?php if ($gtmId): ?>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<?= htmlspecialchars($gtmId) ?>');</script>
<?php endif; ?>
</head>
<body>
<!-- GTM noscript сразу после <body> -->
<?php if ($gtmId): ?>
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<?= htmlspecialchars($gtmId) ?>"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<?php endif; ?>
ID контейнера хранить в b_option (таблица настроек) через административный интерфейс — не в коде, чтобы маркетолог мог менять без деплоя.
dataLayer для страниц товара
Для работы расширенной электронной торговли (GA4 Ecommerce) нужен dataLayer с данными товара. В шаблоне компонента bitrix:catalog.element или в result_modifier.php:
// bitrix/templates/.default/components/bitrix/catalog.element/.default/result_modifier.php
if (!empty($arResult['CATALOG_PRICE']['BASE']['PRICE'])) {
$product = [
'item_id' => $arResult['ID'],
'item_name' => $arResult['NAME'],
'price' => (float)$arResult['CATALOG_PRICE']['BASE']['PRICE'],
'currency' => $arResult['CATALOG_PRICE']['BASE']['CURRENCY'],
'item_category' => $arResult['SECTION']['NAME'] ?? '',
'item_brand' => $arResult['PROPERTIES']['BRAND']['VALUE'] ?? ''
];
$this->arResult['GTM_PRODUCT'] = $product;
}
В шаблоне компонента вывести dataLayer перед закрывающим </body>:
<?php if (!empty($arResult['GTM_PRODUCT'])): ?>
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'view_item',
ecommerce: {
currency: '<?= htmlspecialchars($arResult['GTM_PRODUCT']['currency']) ?>',
value: <?= (float)$arResult['GTM_PRODUCT']['price'] ?>,
items: [<?= json_encode($arResult['GTM_PRODUCT'], JSON_UNESCAPED_UNICODE) ?>]
}
});
</script>
<?php endif; ?>
Событие purchase после оплаты
Самое важное событие — факт покупки. В компоненте bitrix:sale.order.ajax или на странице «Спасибо за заказ»:
<?php
// Получить последний заказ текущего пользователя
$orderId = (int)($_SESSION['SALE_ORDER_ID_REDIRECTED'] ?? 0);
if ($orderId > 0) {
$order = \Bitrix\Sale\Order::load($orderId);
if ($order) {
$items = [];
foreach ($order->getBasket() as $basketItem) {
$items[] = [
'item_id' => $basketItem->getProductId(),
'item_name' => $basketItem->getField('NAME'),
'price' => (float)$basketItem->getPrice(),
'quantity' => (int)$basketItem->getQuantity()
];
}
?>
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: '<?= $order->getId() ?>',
value: <?= (float)$order->getPrice() ?>,
currency: '<?= $order->getCurrency() ?>',
items: <?= json_encode($items, JSON_UNESCAPED_UNICODE) ?>
}
});
</script>
<?php
}
}
?>
Добавление в корзину через JS
Событие add_to_cart генерируется в JavaScript при клике на кнопку «Добавить в корзину». Перехватить стандартное событие Битрикс:
// В шаблоне или в /local/templates/.default/js/analytics.js
BX.addCustomEvent('OnBasketChange', function(event) {
if (event.action === 'ADD') {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: event.currency || 'RUB',
value: event.price * event.quantity,
items: [{
item_id: String(event.productId),
item_name: event.productName || '',
price: event.price,
quantity: event.quantity
}]
}
});
}
});
Событие OnBasketChange генерируется модулем sale через BX.Event при AJAX-добавлении в корзину.
Проверка работы
В браузере установить расширение «Tag Assistant» от Google. Оно покажет какие теги GTM сработали, с какими данными и были ли ошибки в dataLayer.
Или через консоль браузера:
// Просмотреть все события в dataLayer
console.table(window.dataLayer);
// Следить за новыми событиями
const origPush = window.dataLayer.push.bind(window.dataLayer);
window.dataLayer.push = function(data) {
console.log('dataLayer push:', data);
return origPush(data);
};
Хранение ID контейнера
Не хардкодить GTM ID в шаблоне — использовать b_option:
// Запись через API
\Bitrix\Main\Config\Option::set('custom', 'gtm_container_id', 'GTM-XXXXXXX');
// Чтение
$gtmId = \Bitrix\Main\Config\Option::get('custom', 'gtm_container_id');
Это позволяет менять ID без правки кода через административный интерфейс или через настройки кастомного модуля.







