Аналитика форм на сайте — настройка в Google Tag Manager

Аналитика форм на сайте — настройка в Google Tag Manager

  • 1 168


Для меня отслеживание форм в аналитике — всегда заноза в заднице. Недавно с обновлением нашего сайта эта задача снова всплыла и снова оказалась не самой простой. К счастью, на этот раз мы справились. Мне помогла статья, в которой описано несколько способов отслеживания форм на сайте для разных случаев. Один из них подошёл и нам.

Проблема

Есть форма, на неё нужно настроить цель в 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 не срабатывает, то этот способ отслеживания вам не подходит, и, возможно, мы напишем ещё одну статью.

Аналитика форм на сайте через Google Tag Manager

 

Шаг 2. Проверяем, что отправляется в Data Layer

В панели предпросмотра кликаем по событию «ajaxComplete», затем переходим во вкладку Data Layer и находим строчку ‘response’. Нужно посмотреть, что там появляется.

Наши формы интегрированы с CRM, так что в ответе видно, что данные отправляются в CRM:

Проверяем, что отправляется в Data Layer

Кроме этого, там должен быть ответ, который выдаётся пользователю после отправки формы.

У нас вообще это «Спасибо, заявка отправлена!», но изначально такой строчки в коде не оказалось, так что пришлось обратиться к программисту и попросить его передавать в 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:

Создаём переменную в Google Tag Manager

И вот, что мы прописываем в имени переменной (в англоязычном интерфейсе нагляднее):

Прописываем имя переменной в Google Tag Manager

Остальное оставляем по умолчанию: «Версия 2» и без галочки напротив «Установить значение по умолчанию».

Переменная готова.

Шаг 4. Определяем, каким должно быть событие в Google Analytics

Прежде чем задать теги, нужно понять, что именно нам важно видеть в Google Analytics. Первое, что вы видите, заходя в раздел Поведение → События → Обзор — это категории событий:

 

Категории событий в Google Tag Manager

Это самая крупная величина. Важно категоризировать события правильно, чтобы не наплодить бестолковых категорий и не усложнить себе жизнь, когда придёт момент анализировать полученные данные.

Например, мы могли бы сделать категорию «успешная заявка» и «не успешная заявка». Но с таким подходом в аналитике будет отображаться слишком много событий, анализировать их будет сложно, в каждое придётся тыкать, чтобы посмотреть детали. Нам же важнее всего знать о самом факте — конверсия случилась. Потому что этот факт отражает поведение пользователей. Остальное — технические детали, их нужно проверять время от времени.

Так что, для отправки форм заявки у нас одна категория — «Формы заявки». В качестве действия по событию мы отправляем страницу, на которой была оформлена заявка, и только в качестве ярлыка — успешно или не успешно прошло событие:

Формы заявки в Google Tag Manager

Со временем, когда данных накопится достаточно, мы будем понимать, какие страницы конвертируют лучше всего.

Возможно, у вас есть свой регламент для ведения аккаунта Google Analytics и вы будете придерживаться собственной практики.

Итак, определились, как отправлять событие в Google Analytics. Теперь идём обратно в GTM и настраиваем всё это добро.

Создаём новый тег. Я решила, что для нас будет оптимально настроить два тега: один для успешной отправки формы, другой — для случаев, когда форма была заполнена, но данные до нас не дошли. Ведь на сайтах всегда что-нибудь ломается, и важно об этом быстро узнать.

Возможно, два тега — это не лучший вариант, потому что тегов становится слишком много. Есть другой вариант — сделать один тег, а в ярлык события отправлять как раз недавно созданную нами переменную — DLV-attribute.response. Тогда, по идее, в ярлыке события в аналитике будет отображаться Form Submitted или Data lost.

Но наш ответ, который отправляется в Data Layer, выглядит так:

Ответ, который отправляется в Data Layer

Поэтому, отправляй мы DLV-attribute.response в ярлык события, в аналитике получили бы что-то вроде этого:

Что будет, если отправить DLV-attribute.response в ярлык события

В общем, вы поняли. Так что два тега.

Шаг 5. Настраиваем тег для успешной отправки формы

Создаём новый тег, тип — Universal Analytics. Я назвала его FormSubmitted.

Тип тега — «Событие». Категория, как мы уже решили, — «Формы заявки». В действие я отправляю {{Page Path}} — переменная, которая показывает относительный адрес страницы. Так мы будем знать, какие страницы конвертируют лучше, какие — хуже. В ярлык прописываю «успешно», потому что это тег для успешной отправки формы.

Настраиваем тег для успешной отправки формы

В меню «Настройки Google Analytics» вносим идентификатор отслеживания Google Analytics. Он уже должен быть сохранён в виде переменной. Найти идентификатор отслеживания можно в аккаунте GA: администратор → отслеживание → код отслеживания:

Идентификатор отслеживания Google Analytics

 

Идентификатор отслеживания Google Analytics

Теперь задаём триггер — условие, при котором событие будет отправляться в 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, значит, всё хорошо.

Проверяем работу тегов в Google Tag Manager

Если не сработал, кликаете по тегу, который должен был сработать, появляются сведения о триггере, который вызывает этот тег:

Проверяем работу тегов в Google Tag Manager

У нас на скриншоте три зелёные галочки — это все условия, которые заставляют триггер срабатывать. Если бы какое-то из них не выполнялось, напротив него был бы красный крестик. В общем, благодаря этому легко обнаружить и исправить ошибку.

Ещё один вариант ошибки — если срабатывают даже те теги, которые не должны срабатывать. Значит, в триггере у них одинаковые условия для выполнения. Тогда кликаете по тегу, идёте во вкладку Variables, в обоих тегах ищите переменные, которые у них отличаются. Эти переменные вписываете в условия срабатывания тегов. Иначе — неверные данные в аналитике, невозможность строить прогнозы и планы, всё катится к чертям, компания разоряется, сотрудники остаются без работы.

Надеюсь, вы будете внимательны, правильно настроите формы и сможете получать хорошие данные.