Отслеживание брошенных форм с помощью Google Tag Manager
Руководство по отслеживанию брошенных форм на сайте с помощью шаблона тега Google Tag Manager и собственного JavaScript-кода.
Ситуация довольно распространенная - пользователь частично или полностью заполняет форму на вашем сайте, но не отправляет ее вам по какой-либо причине (отвлекли, передумал, так как она содержит много полей и заполнять ее утомительно, нечаянно закрыл вкладку браузера и не знает, как вернуться назад, техническая проблема при заполнении и т.д). Форма обратной связи, регистрации, заказа или любая другая форма, которую пользователь начал заполнять, но не отправил ее вам, является брошенной (на английском языке закрепился термин form abandonment).
В предыдущем материале моего блога мы познакомились с отслеживанием брошенных форм с помощью специального кода JavaScript, события change и Google Tag Manager. В этой статье разберем еще один способ трекинга брошенных форм - с помощью шаблона тега.
Важно: это решение подойдет не для каждого проекта и не для каждой формы. Постарайтесь во время прочтения статьи вникнуть в логику работы самого кода, который используется в этом шаблоне тега. Я постараюсь максимально описать его функционал, но не гарантирую его работу в вашем проекте.
В качестве примера я буду использовать форму на тестовом сайте graphanalytics.ru:
Шаблон тега
Чтобы отслеживать брошенные формы с помощью GTM, перейдите в свой диспетчер тегов Google, и в разделе Теги откройте галерею общедоступных шаблонов:
В строке поиска введите Form Abandonment. Вы увидите тег Form Abandonment Tracking от PerpetualTechnologies:
Добавьте его к себе в рабочую область:
Примечание: шаблоны сторонних поставщиков в этой общедоступной галерее Google Tag Manager не предоставляются компанией Google. Google не дает никаких гарантий и не принимает на себя никаких обязательств в отношении эффективности, качества и содержимого сервисов и приложений, предоставляемых в шаблонах. Я, как и Google, тоже не несу никакой ответственности за те действия, которые вы совершаете в своем контейнере GTM с использованием сторонних решений, в том числе и с Form Abandonment Tracking.
Этот шаблон будет работать только с формами POST/GET и не будет работать с формами iFrame. И ему требуется несколько разрешений. Во-первых, он добавит специальный скрипт на ваш сайт, который будет отслеживать брошенные формы. Во-вторых, он будет записывать сообщения в консоли разработчика и выводить информацию в режиме предварительного просмотра для отладки. И, наконец, шаблону тега будет нужен доступ к нескольким глобальным переменным для корректной работы.
Как видите, ничего необычного. Многие сторонние шаблоны требуют схожие разрешения. Поэтому в завершение нажмите кнопку Добавить:
После этого в вашем контейнере появится возможность использования шаблона тега Form Abandonment Tracking. Он очень прост в настройке. Единственное, что вам нужно сделать - это в поле DataLayer Event Name указать имя события, которое будет отправлено на уровень данных (dataLayer) при обнаружении брошенной формы.
В поле даже есть подсказка - form_abandoned. Поэтому назвать событие вы можете именно так:
В качестве триггера активации задайте All Pages (Все страницы). В результате шаблон тега по отслеживанию брошенных форм будет выглядеть так:
Таким образом, шаблон будет отправлять событие form_abandoned (или другое, которое вы задали) непосредственно перед тем, как пользователь покидает страницу.
Код, который добавлен через шаблон тег, представлен на GitHub разработчика. Выглядит он так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
(function () { if (typeof document.querySelectorAll === "undefined") { return; } var history = {}; window.addEventListener('beforeunload', function (e) { findUnsubmittedForms().forEach(function (it) { var lastField = it.history[it.history.length - 1].name; var lastFieldType = it.history[it.history.length - 1].type; window.dataLayer.push({ 'event': window.fat_event_name, 'form': it.name, 'dropped_at_field_name': lastField, 'dropped_at_field_type': lastFieldType }); }); }); window.addEventListener("load", function () { document.addEventListener("change", function (e) { var target = e.target; if (target && target.tagName && (target.tagName.toUpperCase() === "INPUT" || target.tagName.toUpperCase() === "SELECT" || target.tagName.toUpperCase() === "TEXTAREA")) { var form = target.form; if (form) { var formName = form.getAttribute("name") || form.getAttribute("aria-label") || form.id || "unlabeled_form"; if (typeof history[formName] === "undefined") { history[formName] = []; } var nextUnfilledField = getNextUnfilledField(form); if (nextUnfilledField) { var fieldName = getFieldName(nextUnfilledField); if (fieldName && (!history[formName].length || history[formName][history[formName].length - 1].name !== fieldName)) { history[formName].push({ name: fieldName, type: nextUnfilledField.tagName.toLowerCase() }); } } } } }); }); function getNextUnfilledField(form) { var elements = form.querySelectorAll("input, select, textarea"); for (var i = 0; i < elements.length; i++) { var element = elements[i]; if (isElementUnfilled(element) && isElementVisible(element)) { return element; } } return null; } function isElementUnfilled(element) { if (element.tagName.toUpperCase() === "INPUT") { var type = element.type.toLowerCase(); if (type === "checkbox" || type === "radio") { return !element.checked; } else { return !element.value; } } else if (element.tagName.toUpperCase() === "SELECT" || element.tagName.toUpperCase() === "TEXTAREA") { return !element.value; } return false; } function isElementVisible(element) { return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); } function getFieldName(element) { var name = element.getAttribute("name"); if (name && /\d/.test(name)) { var label = findLabel(element); if (label) { return label.textContent.trim(); } } return name || "unlabeled_field"; } function findLabel(element) { var parent = element.parentElement; while (parent) { var label = parent.querySelector("label[for='" + element.id + "']") || parent.querySelector("label"); if (label) { return label; } parent = parent.parentElement; } return null; } function findUnsubmittedForms() { var unsubmittedForms = []; for (var name in history) { if (history.hasOwnProperty(name) && hasNoFormSubmitEvent(name)) { var formHistory = history[name]; var lastHistoryElement = formHistory[formHistory.length - 1]; unsubmittedForms.push({ name: name, history: formHistory, lastFieldElement: lastHistoryElement ? lastHistoryElement.element : null }); } } return unsubmittedForms; } function hasNoFormSubmitEvent(name) { for (var i = 0; i < window.dataLayer.length; i++) { var event = window.dataLayer[i]; if (isFormSubmitEvent(event) && getFormName(event) === name) { return false; } } return true; } function isFormSubmitEvent(e) { return e.event === 'gtm.formSubmit'; } function getFormName(e) { var formElement = e['gtm.element']; return formElement.getAttribute("name") || formElement.getAttribute("aria-label") || formElement.id || "unlabeled_form"; } })(); |
Вы можете воспользоваться любым чат-ботом ИИ, чтобы расшифровать этот скрипт и узнать как он работает. Но если кратко, этот код отслеживает прогресс заполнения форм на веб-странице и отправляет событие в dataLayer при уходе пользователя со страницы без отправки формы. Он фиксирует последнее заполненное поле в каждой форме.
Подробнее о JS-коде:
1. проверка querySelectorAll - убеждается, что браузер поддерживает querySelectorAll. Если нет, код завершается;
2. history объект - хранит историю заполнения полей для каждой формы. Ключи - имена форм, значения - массивы объектов {name: имя_поля, type: тип_поля};
3. beforeunload обработчик - cрабатывает перед тем, как пользователь покинет страницу. Вызывается функция findUnsubmittedForms() для получения списка незаполненных форм. Для каждой такой формы отправляет событие в dataLayer с информацией о форме и последнем заполненном поле;
4. load и change обработчики - после загрузки страницы, обработчик отслеживает событие change и изменения в полях ввода (input, select, textarea). Когда пользователь изменяет значение поля:
- определяется форма, к которой принадлежит поле;
- если история для этой формы еще не создана, она инициализируется;
- вызывается функция getNextUnfilledField() для поиска следующего незаполненного поля в форме;
- если такое поле найдено, его имя добавляется в историю формы, если оно еще не последнее в истории.
Функции:
- getNextUnfilledField(form) - находит первое незаполненное и видимое поле в форме;
- isElementUnfilled(element) - проверяет, заполнено ли поле. Для чекбоксов и радиокнопок проверяет checked, для остальных - наличие значения;
- isElementVisible(element) - проверяет, видимо ли поле на странице;
- getFieldName(element) - возвращает имя поля. Если имя содержит цифры, пытается найти <label> для поля и использовать его текст;
- findLabel(element) - ищет <label> для поля или просто наличие <label> в родительских элементах;
- findUnsubmittedForms() - возвращает массив незаполненных форм. Форма считается незаполненной, если для нее есть записи в history и нет события отправки gtm.formSubmit в dataLayer;
- hasNoFormSubmitEvent(name) - проверяет, было ли событие отправки формы с указанным именем в dataLayer;
- isFormSubmitEvent(e) и getFormName(e) - вспомогательные функции для проверки события отправки формы и получения имени формы из события.
Следующим этапом создайте триггер специального события с названием события, которое вы указали в шаблоне тега. В моем примере - это form_abandoned:
Поскольку на уровень данных (dataLayer) передается информация по имени формы, имени поля и типу поля, которые были заполнены последними в брошенной форме, мы можем создать три пользовательских переменных типа Переменные уровня данных со следующими именами - form, dropped_at_field_name и dropped_at_field_type:
Теперь все, что осталось сделать - это создать теги для Яндекс Метрики и Google Analytics 4.
Для Google Analytics 4 выберите тег типа Google Аналитика: событие GA4. Задайте:
- идентификатор потока данных Google Analytics 4;
- название события (например - form_abandoned).
У параметров события вы можете задать произвольные названия (например - form_name, field_name и field_type), а вот значениями нужно указать переменные уровня данных, созданные на предыдущем шаге. В качестве триггера активации задайте триггер специального события.
Итоговый тег события GA4 может выглядеть так:
Чтобы передавать информацию о брошенных формах в Яндекс Метрику, перейдите в счетчик и создайте цель типа JavaScript-событие. Укажите название цели и ее идентификатор. Например, form_abandoned:
Скопируйте полученный код цели из интерфейса Метрики и вставьте его в Google Tag Manager, создав отдельный тег типа Пользовательский HTML. Для передачи параметра события необходимо добавить четвертым аргументом такую конструкцию:
1 2 3 4 5 6 7 |
<script> ym(XXXXXXXX,'reachGoal','form_abandoned', { 'form_name':{{form}}, 'field_name':{{dropped_at_field_name}}, 'field_type':{{dropped_at_field_type}} }) </script> |
, где вместо:
- XXXXXXXX - ваш идентификатор счетчика Яндекс Метрики;
- form_abandoned - идентификатор цели;
- form_name, field_name, field_type - названия параметров событий;
- {{form}}, {{dropped_at_field_name}}, {{dropped_at_field_type}} - значения параметров событий, переменные уровня данных.
Триггер активации - триггер специального события, тот же самый, что и для Google Analytics 4:
Сохраните теги. Как показали мои эксперименты, я не всегда смог отлавливать нужное событие в режиме предварительного просмотра GTM. Поэтому я предлагаю сразу опубликовать контейнер и проводить отладку в консоли разработчика, используя специальные расширения для браузера Google Chrome - Google Analytics Debugger (нужно для включения отладки и инструмента DebugView в Google Analytics 4) и Analytics Debugger. Для Яндекс Метрики - отладчик _ym_debug=2.
Установив расширения, активируйте их. Затем перейдите на свой сайт и откройте консоль разработчика (клавиша F12 в Google Chrome или вызов контекстного меню правой кнопкой мыши - Просмотреть код). В консоли разработчика откройте вкладку расширения Analytics Debugger. Заполните форму, но не до конца. Перейдите на другую страницу или просто перезагрузите существующую (если у вас одностраничный сайт).
Вы должны увидеть со
На шкале событий вы должны будете увидеть событие с названием form_abandoned (если используете такое), а в окне правее - dataLayer со всеми параметрами, о которых я писал выше:
- form - название брошенной формы;
- dropped_at_field_name - имя последнего заполненного поля брошенной формы;
- dropped_at_field_type - тип последнего заполненного поля брошенной формы;
Поскольку в форме graphanalytics.ru я заполнил все поля, но не отправил ее, моим последним полем брошенной формы было как раз поле с телефоном, у которого тип - input, а имя (атрибут name) - number:
Поскольку мы активировали расширение GA Debugger, которое активирует инструмент DebugView в интерфейсе GA4, то перейдя в него, мы можем наблюдать те же самые данные:
Примерно через 24 часа статистика по отслеживаемым параметрам будет доступна для событий в стандартных отчетах Google Analytics 4 и Исследованиях. Если вы желаете видеть данные по параметрам событий, передаваемых в теге, вам необходимо создать специальные параметры с областью действия Событие. Названия параметров можно задать произвольные, а вот параметры событий должны быть точно такими же, которые вы указали в теге события GA4 в Google Tag Manager. В моем примере - это form_name, field_name и field_type:
Отладка с помощью параметра _ym_debug=2 для Яндекс Метрики:
Информация по отправленным параметрам событий будет доступна в отчете Параметры событий.
Примечание: если у вас не получается работать с шаблоном тега, вы можете попробовать скопировать код из статьи и вставить его напрямую в исходный код сайта, до загрузки контейнера Google Tag Manager. А сам шаблон тега просто удалите из рабочей области. Все остальные шаги настройки остаются без изменений.
Код, который можно установить напрямую (немного изменен + добавлены консольные уведомления):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
<script> (function () { if (typeof document.querySelectorAll === "undefined") { console.log("querySelectorAll is undefined, exiting."); return; } var history = {}; var form_abandoned = 'form_abandoned'; // <-- Объявление переменной window.addEventListener('beforeunload', function (e) { console.log("Before unload event triggered."); findUnsubmittedForms().forEach(function (it) { var lastField = it.history[it.history.length - 1].name; var lastFieldType = it.history[it.history.length - 1].type; console.log("Pushing to dataLayer:", { 'event': form_abandoned, 'form': it.name, 'dropped_at_field_name': lastField, 'dropped_at_field_type': lastFieldType }); window.dataLayer.push({ 'event': form_abandoned, 'form': it.name, 'dropped_at_field_name': lastField, 'dropped_at_field_type': lastFieldType }); }); }); window.addEventListener("load", function () { console.log("Window loaded, adding change event listener."); document.addEventListener("change", function (e) { var target = e.target; if (target && target.tagName && (target.tagName.toUpperCase() === "INPUT" || target.tagName.toUpperCase() === "SELECT" || target.tagName.toUpperCase() === "TEXTAREA")) { var form = target.form; if (form) { var formName = form.getAttribute("name") || form.getAttribute("aria-label") || form.id || "unlabeled_form"; console.log("Change detected in form:", formName); if (typeof history[formName] === "undefined") { history[formName] = []; } var nextUnfilledField = getNextUnfilledField(form); if (nextUnfilledField) { var fieldName = getFieldName(nextUnfilledField); console.log("Next unfilled field detected:", fieldName); if (fieldName && (!history[formName].length || history[formName][history[formName].length - 1].name !== fieldName)) { history[formName].push({ name: fieldName, type: nextUnfilledField.tagName.toLowerCase() }); console.log("Field added to history:", history[formName]); } } } } }); }); function getNextUnfilledField(form) { var elements = form.querySelectorAll("input, select, textarea"); for (var i = 0; i < elements.length; i++) { var element = elements[i]; if (isElementUnfilled(element) && isElementVisible(element)) { console.log("Unfilled and visible element found:", element); return element; } } return null; } function isElementUnfilled(element) { if (element.tagName.toUpperCase() === "INPUT") { var type = element.type.toLowerCase(); if (type === "checkbox" || type === "radio") { return !element.checked; } else { return !element.value; } } else if (element.tagName.toUpperCase() === "SELECT" || element.tagName.toUpperCase() === "TEXTAREA") { return !element.value; } return false; } function isElementVisible(element) { return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length); } function getFieldName(element) { var name = element.getAttribute("name"); if (name && /\d/.test(name)) { var label = findLabel(element); if (label) { return label.textContent.trim(); } } return name || "unlabeled_field"; } function findLabel(element) { var parent = element.parentElement; while (parent) { var label = parent.querySelector("label[for='" + element.id + "']") || parent.querySelector("label"); if (label) { return label; } parent = parent.parentElement; } return null; } function findUnsubmittedForms() { var unsubmittedForms = []; for (var name in history) { if (history.hasOwnProperty(name) && hasNoFormSubmitEvent(name)) { var formHistory = history[name]; var lastHistoryElement = formHistory[formHistory.length - 1]; console.log("Unsubmitted form found:", name); unsubmittedForms.push({ name: name, history: formHistory, lastFieldElement: lastHistoryElement ? lastHistoryElement.element : null }); } } return unsubmittedForms; } function hasNoFormSubmitEvent(name) { console.log("Checking for form submit events for:", name); for (var i = 0; i < window.dataLayer.length; i++) { var event = window.dataLayer[i]; if (isFormSubmitEvent(event) && getFormName(event) === name) { console.log("Form submit event found for:", name); return false; } } return true; } function isFormSubmitEvent(e) { return e.event === 'gtm.formSubmit'; } function getFormName(e) { var formElement = e['gtm.element']; return formElement.getAttribute("name") || formElement.getAttribute("aria-label") || formElement.id || "unlabeled_form"; } })(); </script> |
Запасной вариант
Если по какой-то причине у вас не работает шаблон тега и скрипт выше, вы можете использовать другое решение. Эта настройка немного сложнее предыдущей, поскольку требует ручного управления и изменения вами самого кода. Но зато она интереснее - мы можем регистрировать не только событие с участием последнего поля брошенной формы, но и передать весь путь полей формы - начиная от первого и заканчивая последним.
Добавьте нижеприведенный скрипт в новый тег типа Пользовательский HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<script> (function() { var formPath, i; var checkSubmit = function() { i = window.dataLayer.length - 1; while (i > -1) { if (window.dataLayer[i]['event'] === 'gtm.formSubmit') { return true; } i--; } }; var formSelector = '#form1'; // Селектор CSS вашей формы. По умолчанию это первая форма на странице var attribute = 'name'; var history = []; window.addEventListener('beforeunload', function() { if (!checkSubmit()) { // Если history пустой, то устанавливаем 'no', иначе - соединяем историю var formPathValue = history.length > 0 ? history.join(' > ') : 'no'; window.dataLayer.push({ 'event' : 'form_abandonment', 'formPath' : formPathValue }); } }); // Отслеживание последнего поля формы, с которым взаимодействовали с помощью события "change" document.querySelector(formSelector).addEventListener('change', function(e) { history.push(e['target'].getAttribute(attribute)); }); })(); </script> |
Вместо #form1 в строке объявления переменной var formSelector вставьте селектор CSS вашей формы. Если вы не знаете как это сделать, обязательно прочитайте дополнительные материалы по нахождению селектора CSS у HTML-элемента:
- CSS-селекторы в Google Tag Manager. Часть I
- Селекторы в jQuery. Часть II
- Регулярные выражения в CSS-селекторах и GTM
Чтобы найти селектор у формы, необходимо проинспектировать этот элемент с помощью консоли разработчика (клавиша F12 в Google Chrome или вызов контекстного меню правой кнопкой мыши - Просмотреть код). Найдя элемент верхнего уровня (как правило, это тег <form>), нажмите на него правой кнопкой мыши и выберите Copy - Copy selector:
Вставьте скопированное значение селектора формы в скрипт. В качестве триггера активации задайте All Pages (Все страницы) или конкретную страницу, на которой размещена ваша форма. В конечном счете ваш тег должен выглядеть примерно так:
Этот код помогает отслеживать, какие поля формы пользователь заполнял, и регистрирует событие form_abandonment, когда пользователь покидает страницу, не отправив форму. На уровень данных так же передается параметр formPath, в котором содержится путь к полям формы, с которыми взаимодействовал пользователь (хранится в history). Это значение извлекается из атрибута name. Если такого атрибута у вашей формы нет, то вы не получите итоговый путь. Попросите разработчика прометить форму нужными данными, либо замените в коде значение для переменной attribute.
Запустив режим предварительного просмотра GTM, выполните те же самые шаги, что и для шаблона тега (см. выше). Заполните форму на сайте, но не до конца. Перейдите на другую страницу или просто перезагрузите существующую (если у вас одностраничный сайт). На шкале событий вы должны будете увидеть событие с названием form_abandonment. Откройте Вызов API. Там вы увидите информацию по дополнительным параметрам:
Откройте Вызов API. Там вы увидите параметр formPath, в котором содержится путь к полям формы, с которыми взаимодействовал пользователь. Эти значения извлекаются из атрибута name:
Сами значения в пути разделяются символом >. В моем примере путь получился таким: your_name > your_site > meemail. Это три поля формы: Имя > Ссылка на сайт > E-mail. Остальные я не заполнил, чтобы продемонстрировать отслеживание брошенных форм с помощью этого кода.
Чтобы извлечь путь к полям формы, в Google Tag Manager создайте пользовательскую переменную типа Переменная уровня данных с именем formPath:
Сохраните переменную. Теперь создайте триггер специального события с названием события form_abandonment. В качестве дополнительного условия активации задайте DLV - formPath не равно no:
Это нужно для того, чтобы тег не отправлял ложные события с пустыми данными в аналитику после перезагрузки пользователем страницы или ухода с сайта. Сохраните триггер. Теперь вы можете создать теги для передачи этой информации в Яндекс Метрику и Google Analytics 4.
Для Google Analytics 4 выберите тег типа Google Аналитика: событие GA4. Задайте:
- идентификатор потока данных Google Analytics 4;
- название события (например - form_abandonment).
У параметра события вы можете задать произвольное название (например - form_path), а вот значением нужно указать переменную уровня данных, созданную на предыдущем шаге. Не забудьте, что длина значения параметра события в Google Analytics 4 не может превышать 100 символов. Поэтому если у вас много полей в форме, то путь в параметре события может отображаться не полностью.
В качестве триггера активации задайте триггер специального события, созданный ранее. Итоговый тег может выглядеть так:
Чтобы передавать информацию о брошенных формах в Яндекс Метрику, перейдите в счетчик и создайте цель типа JavaScript-событие. Укажите название цели и ее идентификатор. Например, form_abandonment:
Скопируйте полученный код цели из интерфейса Метрики и вставьте его в Google Tag Manager, создав отдельный тег типа Пользовательский HTML. Для передачи параметра события необходимо добавить четвертым аргументом такую конструкцию:
1 2 3 |
<script> ym(XXXXXXXX,'reachGoal','form_abandonment', {'form_path':{{DLV - formPath}}}) </script> |
, где вместо:
- XXXXXXXX - ваш идентификатор счетчика Яндекс Метрики;
- form_abandonment - идентификатор цели;
- form_path - название параметра события;
- {{DLV - formPath}} - значение параметра события, переменная уровня данных.
Триггер активации - триггер специального события, тот же самый, что и для Google Analytics 4:
Сохраните теги. Проверить настройки отслеживания в Google Analytics 4 можно с помощью отчета В реальном времени, или перейдя в инструмент DebugView:
Примерно через 24 часа статистика по отслеживаемым параметрам будет доступна для событий в стандартных отчетах Google Analytics 4 и Исследованиях. Если вы желаете видеть данные по путям полей формы, вам необходимо создать специальный параметр с областью действия Событие. Название параметра можно задать произвольное, а вот параметр события должен быть точно таким же, который вы указали в теге события GA4 в Google Tag Manager. В моем примере - это form_path:
В Яндекс Метрике информация по отправленному параметру события будет доступна в отчете Параметры событий.
Итоги
В этом руководстве мы с вами разобрали два варианта отслеживания брошенных форм с помощью Google Tag Manager - используя готовый шаблон тега и собственный код JavaScript. Одно из них позволяет отслеживать последнее заполненное пользователем поле брошенной формы, а другое - весь путь полей брошенной формы.
Как видите, есть разные реализации и способы отслеживания таких форм. И не всегда решение "из коробки" может быть применено к форме вашего сайта. Поскольку текущие коды являются универсальными, они направлены на отслеживание классических форм, самых распространенных, которые заключены в тег <form>, а также имеют соответствующие атрибуты полей формы (name, aria-label, form.id). Такие формы встречаются часто, но используются не на всех сайтах.
Если у вас нестандартная форма, и она не имеет соответствующих атрибутов для отслеживания, вероятно, вы не сможете использовать как шаблон тега из этой статьи, так и запасной вариант с собственным JS-кодом. Тогда вам может потребоваться помощь программиста, чтобы привести ваши формы к нужному стандарту. Если это невозможно, тогда вам придется разрабатывать собственное решение под свои формы, ориентируясь на коды из этого материала. Попробуйте взять их за основу и воспользоваться помощью чат-бота ИИ. Если он не сможет скорректировать код под ваши формы - наймите специалиста, который выполнит эту задачу за вас.