15 мин чтения100CTR
JavaScript-события в Яндекс Метрике: reachGoal, параметры и проверка
Как создать цель «Целевое событие» и вызвать reachGoal на кнопке, форме и AJAX-заявке, передать доход и параметры, настроить событие через GTM или Яндекс Тег Менеджер и проверить отладчиком.

JavaScript-событие — цель Метрики, которую засчитывает сам сайт: в нужный момент код страницы вызывает ym(номер_счётчика, 'reachGoal', 'идентификатор'). В Метрике такая цель создаётся с типом «Целевое событие» и тем же идентификатором. Способ подходит для действий, после которых адрес страницы не меняется: успешная AJAX-заявка, клик по кнопке калькулятора, открытие попапа, шаг квиза. Вместе с целью можно передать доход и параметры визита, а поставить вызов — прямо в код сайта, через Google Tag Manager или Яндекс Тег Менеджер.
Когда нужна JavaScript-цель
Простые цели Метрики — «Отправка формы», «Клик по кнопке», «Клик по номеру телефона» — настраиваются без программиста, и для многих сайтов их хватает. JavaScript-событие нужно, когда стандартная цель считает неточно или вообще не видит действие.
| Задача | Простая цель | JavaScript-событие |
|---|---|---|
| Заявка через AJAX-форму без страницы «Спасибо» | «Отправка формы» засчитывается и при ошибке заполнения, формы на div не видит |
Срабатывает только после ответа сервера об успешной отправке |
| Кнопка в меню, которая есть на всех страницах | Работает, пока не поменялась вёрстка | Не зависит от вёрстки |
| Шаг калькулятора, квиза, корзины в SPA (одностраничном приложении) | Не видит | Срабатывает на любом шаге |
| Доход с суммой заказа | Только фиксированная ценность цели | Передаётся сумма конкретного заказа |
| Дополнительные данные: тариф, тип формы, город | Нет | Передаются параметрами визита |
Все типы целей и их ограничения разобраны в статье цели в Яндекс Метрике. Здесь — только то, что касается кода.
Как создать цель «Целевое событие»
- Откройте счётчик в Метрике, раздел «Цели», и нажмите «Добавить цель».
- Выберите тип «Целевое событие».
- Введите название — его увидят в отчётах и в Директе, например «Заявка: форма расчёта».
- Выберите условие и введите идентификатор цели, например
lead_form. - Оставьте онлайн-передачу данных: офлайн-вариант нужен для загрузки событий из CRM файлом или через API.
- При необходимости укажите доход — фиксированную ценность цели.
- Нажмите «Добавить цель». Статистика начнёт собираться через несколько минут.
Форма цели «Целевое событие»: название, условие и идентификатор, который потом передаёт код сайта
Скриншоты — из официальной справки Яндекс Метрики: «Целевое событие».
Цель можно создать до того, как разработчик добавит код: достижения появятся с первого вызова reachGoal.
Идентификатор цели и условия
Идентификатор — служебная строка, которую передаёт код сайта. Название цели можно менять когда угодно, идентификатор в Метрике и в коде должен совпадать точно. Пишите его латиницей в нижнем регистре, без пробелов, через подчёркивание: lead_form, calc_open, quiz_step_3.
Для условий «совпадает» и «содержит» в идентификаторе нельзя использовать символы / \ & # ? = ". Знак + заменяют на %2B.
| Условие | Как работает | Когда использовать |
|---|---|---|
| Совпадает | Цель срабатывает на один идентификатор | Одна конкретная заявка или кнопка |
| Содержит | Цель срабатывает на все идентификаторы с этой частью | Общая цель «Любая заявка» для lead_header, lead_footer, lead_popup с условием lead_ |
| Регулярное выражение | Произвольный шаблон, например `button | buy` |
Условие «содержит» с коротким фрагментом ловит лишнее: button совпадёт с goal-button и buy-button-mobile. Указывайте фрагмент подлиннее. В одной цели можно задать несколько условий, они работают по логике «ИЛИ».
Метод reachGoal: синтаксис
ym(XXXXXXXX, 'reachGoal', target[, params[, callback[, ctx]]]);
| Аргумент | Тип | Что передаёт |
|---|---|---|
XXXXXXXX |
Число | Номер счётчика. Где его взять — в статье номер счётчика Метрики |
target |
Строка, обязательный | Идентификатор цели |
params |
Объект | Параметры визита, в том числе доход: order_price (или price) и currency |
callback |
Функция | Вызывается после отправки данных |
ctx |
Объект | Контекст, доступный внутри callback через this |
Код счётчика объявляет функцию ym сразу при загрузке, поэтому вызов, сделанный до загрузки библиотеки tag.js, встаёт в очередь и отправится позже. Ошибка будет, только если код счётчика на странице отсутствует или стоит ниже вызова цели.
Одну цель можно вызывать с разных страниц и элементов: Метрика считает все вызовы с этим идентификатором. Разные действия лучше отслеживать разными целями с разными идентификаторами — иначе в отчёте их не разделить.
Примеры кода для кнопок и форм
Во всех примерах 12345678 — номер счётчика, его нужно заменить на свой.
Клик по кнопке или ссылке
Самый короткий вариант — атрибут onclick:
<button type="button" onclick="ym(12345678, 'reachGoal', 'calc_open'); return true;">
Рассчитать стоимость
</button>
<a href="/price.pdf" onclick="ym(12345678, 'reachGoal', 'price_download'); return true;">
Скачать прайс
</a>
Если вёрстку правит не программист или кнопок много, удобнее один скрипт с обработчиком. Он находит кнопки по классу и работает даже для элементов, которые появились на странице позже:
<script>
document.addEventListener('click', function (e) {
if (e.target.closest('.js-order-button') && typeof ym === 'function') {
ym(12345678, 'reachGoal', 'order_click');
}
});
</script>
Кнопкам, клики по которым нужно считать, достаточно добавить класс js-order-button.
Обычная форма с перезагрузкой страницы
<form action="/send.php" method="post" onsubmit="ym(12345678, 'reachGoal', 'lead_form'); return true;">
...
<button type="submit">Отправить</button>
</form>
Событие submit не наступает, если браузер не пропустил форму по встроенной проверке полей (required, type="email"). Но если поля проверяет сервер и возвращает ошибку, цель уже засчитана. Для таких форм надёжнее страница благодарности с целью «Посещение страниц» или вызов цели после ответа сервера.
AJAX-форма: цель после успешной отправки
Вызов ставят в обработчик успешного ответа, а не на клик по кнопке:
form.addEventListener('submit', function (e) {
e.preventDefault();
fetch('/api/lead', { method: 'POST', body: new FormData(form) })
.then(function (response) {
if (response.ok) {
ym(12345678, 'reachGoal', 'lead_form');
showThanks();
}
});
});
С jQuery — то же самое в success:
$.ajax({
url: '/api/lead',
method: 'POST',
data: $('#lead').serialize(),
success: function () {
ym(12345678, 'reachGoal', 'lead_form');
}
});
Готовые плагины форм обычно генерируют своё событие об успешной отправке. Например, Contact Form 7 для WordPress вызывает событие wpcf7mailsent, когда письмо отправлено:
document.addEventListener('wpcf7mailsent', function () {
ym(12345678, 'reachGoal', 'lead_form');
});
В Тильде формы и кнопки отправляют события в Метрику сами, если счётчик подключён через «Аналитику». Для счётчика, вставленного кодом, вызов придётся добавить скриптом.
Цель с переходом на другую страницу
Если сразу после цели ваш скрипт уводит посетителя на другую страницу, переход лучше делать в callback. Запасной таймер нужен на случай, если счётчик заблокирован расширением и callback не вызовется:
function goWithGoal(url) {
var done = false;
function go() { if (!done) { done = true; location.href = url; } }
ym(12345678, 'reachGoal', 'checkout_start', {}, go);
setTimeout(go, 1000);
}
Старый код счётчика
На сайтах со старым кодом (yaCounter12345678 = new Ya.Metrika(…), библиотека watch.js) цели вызывают так: yaCounter12345678.reachGoal('lead_form'). Такой код не поддерживает панель отладки _ym_debug=2 и часть новых возможностей. Лучше заменить его на актуальный.
Несколько счётчиков на странице
reachGoal отправляет цель только в счётчик с указанным номером. Если на сайте два счётчика и цель нужна в обоих, создайте её в каждом и вызовите метод дважды — с каждым номером.
Доход и параметры визита
Доход по цели
Доход передают в params полями order_price (или price) и currency — трёхбуквенным кодом валюты по ISO 4217:
ym(12345678, 'reachGoal', 'order', {order_price: 4500, currency: 'RUB'});
Сумма может быть динамической, например из элемента страницы:
var price = parseFloat(document.querySelector('.cart-total').textContent);
ym(12345678, 'reachGoal', 'order', {order_price: price, currency: 'RUB'});
Если передать неподдерживаемую валюту, вместо суммы и валюты уйдут нулевые значения. Если валюту не указать, сумма считается в условных единицах. Переданный доход появляется в отчётах Метрики, а в Директе по нему считаются доход, ДРР (доля рекламных расходов) и ROI. Для интернет-магазина данные о товарах и заказах точнее передавать через электронную коммерцию.
Параметры визита
Параметры визита — произвольные данные, которые привязываются к текущему визиту: тип формы, выбранный тариф, место кнопки на странице. По ним строят отчёты и сегменты. Передать их можно третьим аргументом reachGoal или отдельным методом params:
// вместе с целью
ym(12345678, 'reachGoal', 'lead_form', {form: {type: 'callback', place: 'header'}});
// без цели
ym(12345678, 'params', {calc: {tariff: 'pro', months: 12}});
Вложенный объект создаёт следующий уровень в отчёте: form → type → callback. Метрика обрабатывает значения по типу: для строк считает количество каждого значения, для чисел — сумму и среднее. Поэтому числа передавайте без кавычек: months: 12, а не months: '12'.
Ограничения:
- запрос с данными — не больше 8 КБ;
- до 512 параметров в одном визите;
- в отчётах видно до 10 уровней вложенности;
- параметры можно отправить в любой момент до окончания визита.
Параметры, переданные через reachGoal, попадают в отчёт только при условии, что на счётчике есть отдельная цель «Целевое событие» с этим идентификатором. Если цель создана лишь как шаг составной цели или не создана вовсе, параметры потеряются. Смотрят их в отчётах «Параметры визитов» и «Параметры событий»: проще всего найти их поиском в разделе «Отчёты».
Параметры посетителя и UserID
Параметры посетителя описывают человека, а не визит: статус клиента, тариф, наличие подписки. Метрика привязывает их к посетителю и применяет к его визитам за 90 дней до отправки данных.
ym(12345678, 'userParams', {status: 'vip', plan: 'business', UserID: 12345});
Ключ UserID — ваш собственный идентификатор пользователя, например номер аккаунта в личном кабинете. Остальные ключи называйте как угодно. Ограничения похожи: до 512 параметров в визите, в отчётах видно до 255 символов в названии поля и до 50 — в значении. Данные появляются в отчёте «Параметры посетителей» в течение нескольких часов. Параметры, отправленные через JavaScript, удалить из Метрики нельзя.
params |
userParams |
|
|---|---|---|
| К чему привязаны | К визиту | К посетителю (ClientID или UserID) |
| Примеры данных | Тип формы, шаг квиза, выбранный тариф | Статус клиента, сегмент, тариф подписки |
| Можно передать с целью | Да, через reachGoal |
Нет, отдельным методом |
| Отчёт | «Параметры визитов», «Параметры событий» | «Параметры посетителей» |
Не передавайте в параметры и идентификаторы целей персональные данные: имя, телефон, email, адрес. Достаточно факта отправки формы и обезличенных признаков.
JavaScript-события через Google Tag Manager
GTM (Google Tag Manager) позволяет поставить вызов reachGoal без правки шаблонов сайта, если контейнер уже установлен. Код счётчика при этом может стоять как в шаблоне, так и в самом GTM.
- Включите переменные. В разделе «Переменные» → «Встроенные переменные» нажмите «Настроить» и отметьте переменные кликов и форм: Click ID, Click Classes, Click Text, Form ID, Form Classes.
- Создайте триггер. Для кнопки — тип «Клик — Все элементы» (Click — All Elements), «Некоторые клики» и условие, например Click Classes содержит
js-order-button. Для формы — тип «Отправка формы» (Form Submission) с условием по Form ID. Включите в нём проверку ошибок (Check Validation), чтобы триггер не срабатывал на формы, не прошедшие проверку. - Создайте тег. Тип «Пользовательский HTML», внутри — вызов цели:
Привяжите к тегу созданный триггер.<script> ym(12345678, 'reachGoal', 'lead_form'); </script> - Проверьте в режиме предварительного просмотра. Нажмите «Предварительный просмотр» (Preview), выполните действие на сайте и убедитесь, что тег сработал.
- Опубликуйте контейнер. Пока изменения не опубликованы, на сайте их нет.
Триггер «Отправка формы» в GTM слушает стандартное событие submit, поэтому на AJAX-формах и формах без тега form часто не срабатывает. Надёжный вариант для таких форм — попросить разработчика добавить в обработчик успешной отправки одну строку:
window.dataLayer = window.dataLayer || [];
dataLayer.push({event: 'lead_sent'});
Затем в GTM создайте триггер «Специальное событие» (Custom Event) с названием события lead_sent и привяжите к нему тег с reachGoal. Разработчику не нужно знать номер счётчика и идентификатор цели — их меняет маркетолог в GTM.
Если код Метрики подключён тоже через GTM, тег цели не должен срабатывать раньше тега счётчика. На клики и отправку форм это не влияет, но для целей при загрузке страницы задайте порядок в дополнительных настройках тега (Tag Sequencing).
JavaScript-события через Яндекс Тег Менеджер
Яндекс Тег Менеджер встроен в Метрику и работает поверх установленного счётчика, отдельный код ставить не нужно. Включает его владелец счётчика: «Настройки» → «Счетчик» → «Яндекс Тег Менеджер». Если нужны собственные скрипты, там же подключают функцию «Пользовательский HTML».
Для целей в нём есть готовый тег «Яндекс Метрика» с методом reachGoal. Писать код не нужно, достаточно заполнить поля:
| Поле | Что указать |
|---|---|
| ID счетчика | Номер счётчика |
| Идентификатор цели | Тот же, что в цели «Целевое событие» |
| Доход по цели, валюта | Необязательно: сумма и код валюты, например RUB |
| Поле params | Необязательно: параметры визита в формате JSON, например {"form":"callback"} |
Триггеры похожи на GTM: «Клик», «Отправка формы», «Глубина прокрутки», «Видимость элемента», «Таймер», «Специальное событие» (событие из dataLayer), «История изменений» для SPA-сайтов. Условия активации задают через «Некоторые события»: например, Click Text содержит «Купить» или Click Element соответствует CSS-селектору .widget-button. Перед публикацией изменения проверяют кнопкой «Предварительный просмотр»: в панели дебаггера видно, какие теги сработали.
| Способ | Нужен разработчик | Плюсы | Минусы |
|---|---|---|---|
| Код в шаблоне сайта | Да | Полный контроль, работает с любыми формами | Каждая правка — через разработчика |
| Google Tag Manager | Для AJAX-форм — одна строка dataLayer.push |
Цели меняет маркетолог, есть режим просмотра | Нужен установленный контейнер GTM |
| Яндекс Тег Менеджер | Для AJAX-форм — одна строка dataLayer.push |
Встроен в Метрику, готовый тег reachGoal без кода |
Включает только владелец счётчика |
| Интеграция CMS или конструктора | Нет | Настраивается в админке | Только те события, которые предусмотрел плагин |
Как проверить, что событие срабатывает
- Если в настройках счётчика включено «Не учитывать мои визиты», откройте сайт в режиме инкогнито.
- Добавьте к адресу страницы
?_ym_debug=2(или&_ym_debug=2, если в адресе уже есть параметры). - Выполните действие: нажмите кнопку, отправьте тестовую заявку.
- Откройте панель отладки внизу страницы. На вкладке Events должна появиться запись о достижении цели, на вкладке Console — подробности с идентификатором из
reachGoal. Переданные параметры визита и посетителя показывает вкладка Parameters. - Через несколько минут найдите достижение в отчёте «Конверсии».
Так в отладчике выглядит сработавший вызов reachGoal
Для старого кода используйте _ym_debug=1 и консоль браузера (Ctrl + Shift + J, на Mac — ⌥ + ⌘ + J): вызов цели отмечается строкой Reach goal. Быстро проверить, загрузилась ли библиотека, можно командой typeof ym в консоли: ответ "function" означает, что счётчик на месте. Остальные способы проверки счётчика описаны в статье как проверить Яндекс Метрику.
Если цель срабатывает в отладчике, но не появляется в отчётах, проверьте, совпадает ли идентификатор с условием цели и не попал ли ваш визит под фильтры счётчика. Тестовые визиты ищите в «Конверсиях», а не в отчётах группы «Директ»: переход был не с рекламы.
Частые ошибки
| Симптом | Причина | Что сделать |
|---|---|---|
В консоли ym is not defined |
Код счётчика не стоит на странице или вызов цели выше кода счётчика | Поставить код счётчика на все страницы, вызов — после него |
| Отладчик показывает цель, отчёт пустой | Идентификатор в коде и в Метрике различается: опечатка, другой регистр, пробел | Скопировать идентификатор из настроек цели |
| Цель уходит не в тот счётчик | В вызове чужой или старый номер счётчика | Сверить номер в ym(…) с номером в кабинете |
| Заявок по цели больше, чем в CRM | Вызов стоит на клике по кнопке, а не на успешной отправке; повторные отправки | Перенести вызов в обработчик успешного ответа сервера |
| Цель не срабатывает у части посетителей | Блокировщики рекламы и антивирусы, счётчик не успел загрузиться при медленном соединении | Сверять цифры с CRM, для важных продаж загружать офлайн-конверсии |
| Тег в GTM не срабатывает на AJAX-форме | Триггер «Отправка формы» ждёт стандартный submit |
Отправлять dataLayer.push после успешной отправки |
| Параметры не видны в отчёте | Цель с этим идентификатором не создана или создана только внутри составной цели | Создать отдельную цель «Целевое событие» |
| Числовые параметры без суммы и среднего | Числа переданы строкой в кавычках | Передавать числа без кавычек |
Учитывайте и лимиты: одна и та же цель на счётчике фиксируется не чаще раза в секунду, а за визит — не больше 400 достижений онлайн-целей. Двойной клик по кнопке даст одно достижение, а три отправки формы за визит — три.
JavaScript-цели в Яндекс Директе
Цели Метрики, в том числе JavaScript-события, Директ использует в конверсионных стратегиях, оплате за конверсии и ретаргетинге. Для этого счётчик указывают в настройках кампании, а нужную цель выбирают ключевой. Как связать счётчик с кампанией, подробно описано в статье Яндекс Метрика и Директ.
Для стратегий подходит цель на подтверждённое действие — успешную отправку формы или оформленный заказ. Цель на клик по кнопке «Отправить» учит алгоритм на попытках, включая неудачные. Если заявок мало, добавьте микроцели вроде calc_open или quiz_step_3, а заявки из разных объявлений различайте по UTM-меткам — их удобно собрать в генераторе UTM.
Частые вопросы
Где взять код цели для вставки на сайт?
Код один для всех JavaScript-целей: ym(номер_счётчика, 'reachGoal', 'идентификатор'). Подставьте номер своего счётчика и идентификатор из настроек цели «Целевое событие», а затем поставьте вызов в обработчик нужного действия.
Можно ли настроить JavaScript-событие без программиста?
Частично. Клики по элементам с понятным классом или ID можно отследить через Google Tag Manager или Яндекс Тег Менеджер без правки сайта. Для AJAX-форм всё равно нужна одна строка в обработчике успешной отправки, иначе цель будет считать попытки.
Сколько ждать появления данных в отчёте?
Достижения целей появляются в отчёте «Конверсии» через несколько минут. Параметры посетителей — в течение нескольких часов. Прошлые визиты новая цель не пересчитывает: она считает только вызовы после создания.
Что будет, если вызвать reachGoal, а цель в Метрике не создана?
Достижение не попадёт в отчёты по целям, а параметры, переданные вместе с ним, — в отчёт по параметрам. Создать цель позже можно, но учитываться она начнёт только с момента создания.
Можно ли передать с целью номер заказа или email клиента?
Номер заказа — да, параметром визита. Email, телефон, имя и другие персональные данные передавать не стоит. Для связки визита со сделкой в CRM используют ClientID (метод getClientID) или собственный идентификатор пользователя в UserID.
Как отслеживать шаги на сайте без перезагрузки страницы?
Вызывайте reachGoal с отдельным идентификатором на каждом шаге: quiz_step_1, quiz_step_2 и так далее. В Метрике создайте цель на каждый шаг или составную цель из этих событий — так будет видно, на каком шаге уходят посетители.
Одна цель на несколько кнопок или отдельная на каждую?
Если в Директе и отчётах нужен общий результат — например, все кнопки «Заказать» — используйте один идентификатор или условие «содержит» с общей частью идентификаторов. Если важно сравнить кнопки между собой, дайте каждой свой идентификатор, а место кнопки передавайте параметром визита.