Для меня отслеживание форм в аналитике — всегда заноза в заднице. Недавно с обновлением нашего сайта эта задача снова всплыла и снова оказалась не самой простой. К счастью, на этот раз мы справились. Мне помогла статья, в которой описано несколько способов отслеживания форм на сайте для разных случаев. Один из них подошёл и нам.
Проблема
Есть форма, на неё нужно настроить цель в Google Analytics. Google Analytics работает через Google Tag Manager.
Если для настроек зайти в панель предпросмотра GTM, заполнить форму и отправить её, то в панели появляется событие не gtm.FormSubmit, а gtm.click. Значит, для аналитики не будет разницы, заполнена форма или нет, и, если пользователь просто кликнул по кнопке, то этот клик засчитается за отправку формы. Вот как тут:
Если есть отдельная страница «спасибо», всё проще — можно отслеживать загрузку этой страницы. Но у нас её нет, так что пришлось искать другой способ.
Способ, который я опишу далее, подходит для форм, которые используют ajax. Инструкция описана не сильно подробно, так что я рассчитываю, что вы знакомы с интерфейсом Google Tag Manager, знаете, какие бывают типы тегов и где искать и создавать переменные. Но и разобраться, в случае чего, не сложно.
Читайте также
6 приёмов вёрстки, чтобы сделать удобную форму
Шаг 1. Проверить, используется ли ajax в формах
Для начала проверяем, используют ли формы ajax. Можно, конечно, спросить у программиста, а можно проявить самостоятельность и использовать код, который для этих целей написали Lunametrics. Он всё равно вам ещё понадобится.
Создаёте тег, называете его AjaxListener, выбираете тип тега «Пользовательский HTML», добавляете туда вот этот код:
<script id="gtm-jq-ajax-listen" type="text/javascript">
(function() {
'use strict';
var $;
var n = 0;
init();
function init(n) {
// Ensure jQuery is available before anything
if (typeof jQuery !== 'undefined') {
// Define our $ shortcut locally
$ = jQuery;
bindToAjax();
// Check for up to 10 seconds
} else if (n < 20) {
n++;
setTimeout(init, 500);
}
}
function bindToAjax() {
$(document).bind('ajaxComplete', function(evt, jqXhr, opts) {
// Create a fake a element for magically simple URL parsing
var fullUrl = document.createElement('a');
fullUrl.href = opts.url;
// IE9+ strips the leading slash from a.pathname because who wants to get home on time Friday anyways
var pathname = fullUrl.pathname[0] === '/' ? fullUrl.pathname : '/' + fullUrl.pathname;
// Manually remove the leading question mark, if there is one
var queryString = fullUrl.search[0] === '?' ? fullUrl.search.slice(1) : fullUrl.search;
// Turn our params and headers into objects for easier reference
var queryParameters = objMap(queryString, '&', '=', true);
var headers = objMap(jqXhr.getAllResponseHeaders(), '\n', ':');
// Blindly push to the dataLayer because this fires within GTM
dataLayer.push({
'event': 'ajaxComplete',
'attributes': {
// Return empty strings to prevent accidental inheritance of old data
'type': opts.type || '',
'url': fullUrl.href || '',
'queryParameters': queryParameters,
'pathname': pathname || '',
'hostname': fullUrl.hostname || '',
'protocol': fullUrl.protocol || '',
'fragment': fullUrl.hash || '',
'statusCode': jqXhr.status || '',
'statusText': jqXhr.statusText || '',
'headers': headers,
'timestamp': evt.timeStamp || '',
'contentType': opts.contentType || '',
// Defer to jQuery's handling of the response
'response': (jqXhr.responseJSON || jqXhr.responseXML || jqXhr.responseText || '')
}
});
});
}
function objMap(data, delim, spl, decode) {
var obj = {};
// If one of our parameters is missing, return an empty object
if (!data || !delim || !spl) {
return {};
}
var arr = data.split(delim);
var i;
if (arr) {
for (i = 0; i < arr.length; i++) {
// If the decode flag is present, URL decode the set
var item = decode ? decodeURIComponent(arr[i]) : arr[i];
var pair = item.split(spl);
var key = trim_(pair[0]);
var value = trim_(pair[1]);
if (key && value) {
obj[key] = value;
}
}
}
return obj;
}
// Basic .trim() polyfill
function trim_(str) {
if (str) {
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
}
}
})();
/*
* v0.1.0
* Created by the Google Analytics consultants at http://www.lunametrics.com
* Written by @notdanwilkerson
* Documentation: http://www.lunametrics.com/blog/2015/08/27/ajax-event-listener-google-tag-manager/
* Licensed under the Creative Commons 4.0 Attribution Public License
*/
</script>
Триггером выбираете «Все страницы».
Включаете режим предпросмотра, переходите на сайт и заполняете форму. Если по заполнении формы срабатывает событие «ajaxComplete», значит, наш способ отслеживания вам подходит, так что можно читать дальше. Не выходите из режима предпросмотра и не обновляйте страницу.
Если ajaxComplete не срабатывает, то этот способ отслеживания вам не подходит, и, возможно, мы напишем ещё одну статью.
Шаг 2. Проверяем, что отправляется в Data Layer
В панели предпросмотра кликаем по событию «ajaxComplete», затем переходим во вкладку Data Layer и находим строчку ‘response’. Нужно посмотреть, что там появляется.
Наши формы интегрированы с CRM, так что в ответе видно, что данные отправляются в CRM:
Кроме этого, там должен быть ответ, который выдаётся пользователю после отправки формы.
У нас вообще это «Спасибо, заявка отправлена!», но изначально такой строчки в коде не оказалось, так что пришлось обратиться к программисту и попросить его передавать в Data Layer нужные мне ответы. Решили отдавать два вида ответа: «FORM SUBMITTED», если заявка успешно отправилась, и «DATA LOST», если заявка не ушла в CRM.
В общем, как вы поняли, без программиста будет сложно.
Шаг 3. Создаём переменную
Теперь, когда формы готовы к отслеживанию, идём в аккаунт GTM, меню «Переменные» и создаём новую переменную (кнопка «Создать»).
Назовём переменную DLV-attributes.response, где DLV — это Data Layer Variable, а attribute.response — это путь к ответу, который отдаётся в Data Layer.
Тип переменной — «Переменная уровня данных». В имени переменной указываем attribute.response. Если ошибиться, чуда не произойдёт — attribute.response — это путь к ответу, который отдаётся в Data Layer, посмотрите сами. Вот, что мы видим в Data Layer:
И вот, что мы прописываем в имени переменной (в англоязычном интерфейсе нагляднее):
Остальное оставляем по умолчанию: «Версия 2» и без галочки напротив «Установить значение по умолчанию».
Переменная готова.
Шаг 4. Определяем, каким должно быть событие в Google Analytics
Прежде чем задать теги, нужно понять, что именно нам важно видеть в Google Analytics. Первое, что вы видите, заходя в раздел Поведение → События → Обзор — это категории событий:
Это самая крупная величина. Важно категоризировать события правильно, чтобы не наплодить бестолковых категорий и не усложнить себе жизнь, когда придёт момент анализировать полученные данные.
Например, мы могли бы сделать категорию «успешная заявка» и «не успешная заявка». Но с таким подходом в аналитике будет отображаться слишком много событий, анализировать их будет сложно, в каждое придётся тыкать, чтобы посмотреть детали. Нам же важнее всего знать о самом факте — конверсия случилась. Потому что этот факт отражает поведение пользователей. Остальное — технические детали, их нужно проверять время от времени.
Так что, для отправки форм заявки у нас одна категория — «Формы заявки». В качестве действия по событию мы отправляем страницу, на которой была оформлена заявка, и только в качестве ярлыка — успешно или не успешно прошло событие:
Со временем, когда данных накопится достаточно, мы будем понимать, какие страницы конвертируют лучше всего.
Возможно, у вас есть свой регламент для ведения аккаунта Google Analytics и вы будете придерживаться собственной практики.
Итак, определились, как отправлять событие в Google Analytics. Теперь идём обратно в GTM и настраиваем всё это добро.
Создаём новый тег. Я решила, что для нас будет оптимально настроить два тега: один для успешной отправки формы, другой — для случаев, когда форма была заполнена, но данные до нас не дошли. Ведь на сайтах всегда что-нибудь ломается, и важно об этом быстро узнать.
Возможно, два тега — это не лучший вариант, потому что тегов становится слишком много. Есть другой вариант — сделать один тег, а в ярлык события отправлять как раз недавно созданную нами переменную — DLV-attribute.response. Тогда, по идее, в ярлыке события в аналитике будет отображаться Form Submitted или Data lost.
Но наш ответ, который отправляется в Data Layer, выглядит так:
Поэтому, отправляй мы DLV-attribute.response в ярлык события, в аналитике получили бы что-то вроде этого:
В общем, вы поняли. Так что два тега.
Шаг 5. Настраиваем тег для успешной отправки формы
Создаём новый тег, тип — Universal Analytics. Я назвала его FormSubmitted.
Тип тега — «Событие». Категория, как мы уже решили, — «Формы заявки». В действие я отправляю {{Page Path}} — переменная, которая показывает относительный адрес страницы. Так мы будем знать, какие страницы конвертируют лучше, какие — хуже. В ярлык прописываю «успешно», потому что это тег для успешной отправки формы.
В меню «Настройки Google Analytics» вносим идентификатор отслеживания Google Analytics. Он уже должен быть сохранён в виде переменной. Найти идентификатор отслеживания можно в аккаунте GA: администратор → отслеживание → код отслеживания:
Теперь задаём триггер — условие, при котором событие будет отправляться в Google Analytics.
Шаг 6. Настраиваем триггер для успешной отправки формы
Идём в меню «Триггеры» и создаём новый триггер. Я назвала его AjaxFormSubmitted, чтобы по названию можно было догадаться, для чего он нужен.
В качестве типа триггера выбираем «Пользовательское событие», в качестве имени события — ajaxComplete (не ошибитесь, а то не будет работать). Дальше ставим галочки напротив «Некоторые специальные события» и выбираем условия срабатывания триггера. Здесь как раз и потребуется переменная, которую мы создавали, — DLV-attribute.response. Выбираем её из списка переменных и говорим, что она должна содержать слова «FORM SUBMITTED» (поле чувствительно к регистру) — это тот ответ, который добавлял наш программист в данные, которые отправляются в Data Layer.
В нашем случае пришлось добавить ещё одно условие — click text. У нас на сайте два типа форм: формы заявки и формы подписки на блог. Так вот, они обе используют ajax и при удачной отправке данных обе отправляют ответ FORM SUBMITTED. Переменные Click Text у них различаются, так что по ней можно отличить одну форму от другой.
Шаг 7. Настраиваем тег неуспешной отправки формы
Он будет настраивается аналогично тегу успешной отправки, только передавать другие данные и срабатывать при других условиях.
Создаём новый тег, называем его FormSubmissionFail, тип тега — Событие, Категория — «Форма заявки», Действие — переменная {{Page Path}}, Ярлык — ошибка отправки. И добавляем идентификатор отслеживания.
Триггер создаём новый — AjaxFormSubmission-Failed. Тип — Пользовательское событие, Имя события — ajaxComplete (опять же, ошибаться нельзя), галочка на «Некоторые специальные области» и условием ставим, что переменная DLV-attribute.response содержит ответ «DATA LOST».
Шаг 8. Проверяем работу тегов
Для этого включаем режим предварительного просмотра. Хотя он у вас уже включён, так что нужно нажать на ссылку «Обновить» в плашке с предупреждением о предварительном просмотре.
Идём на сайт, обновляем страницу со сбросом кэша (cmd+shift+R на Mac или ctrl+F5 на Windows). Заполняем форму, которую отслеживаем. В панели предпросмотра после её отправки должно появиться событие ajaxComplete.
Кликаете на него — справа появляется список тегов, которые сработали при отправке формы. Если сработал тег FormSubmitted, значит, всё хорошо.
Если не сработал, кликаете по тегу, который должен был сработать, появляются сведения о триггере, который вызывает этот тег:
У нас на скриншоте три зелёные галочки — это все условия, которые заставляют триггер срабатывать. Если бы какое-то из них не выполнялось, напротив него был бы красный крестик. В общем, благодаря этому легко обнаружить и исправить ошибку.
Ещё один вариант ошибки — если срабатывают даже те теги, которые не должны срабатывать. Значит, в триггере у них одинаковые условия для выполнения. Тогда кликаете по тегу, идёте во вкладку Variables, в обоих тегах ищите переменные, которые у них отличаются. Эти переменные вписываете в условия срабатывания тегов. Иначе — неверные данные в аналитике, невозможность строить прогнозы и планы, всё катится к чертям, компания разоряется, сотрудники остаются без работы.
Надеюсь, вы будете внимательны, правильно настроите формы и сможете получать хорошие данные.