В этой статье я опишу что под капотом у эксперимента типа «Флаги в коде» сервиса Вариокуб (Varioqub) от Яндекс Метрики. Посмотрим, что возвращает код из документации и разберем его по строкам, поймем как он работает и научимся менять его части под свои нужды с помощью скриптов JavsScript, в т.ч. с применением менеджера тегов Google. На примерах разберем почему флаги являются самым крутым и гибким способом проведения экспериментов в Метрике и одним из самых интересных на рынке подобных решений в целом.
Если вам нужен подробный гайд по инструменту «Эксперименты», он есть в моем блоге по ссылке. Кроме гайда в статье разобраны самые частые проблемы и ошибки, связанные с экспериментами.
Итак, давайте погружаться в флаги по следующему плану:
- создаем тестовый эксперимент над которым будем проводить опыты;
- разбираем код из документации и смотрим, что он отдаёт из Метрики и в каком виде;
- настраиваем эксперимент по замене цвета кнопки с помощью JS;
- настраиваем эксперимент с флагами через GTM для разных сценариев;
- изучаем какие части кода на что менять, чтобы совершать разные действия на сайте с флагами.
Создадим эксперимент в интерфейсе Яндекс Метрики
- Зайдите в Метрику и на вкладке «Эксперименты» создайте новый (если не знаете как, читайте предыдущую статью).
- Введите общие настройки (название, описание, условия и метрики эксперимента).
- Выберите тип эксперимента «Флаги». Контрольный вариант можете оставить без изменений или изменять — это на ваше усмотрение.
- В моем примере будет два флага (color и content) и три экспериментальных выборки со своими значениями флагов:
Запомните настройки тестового эксперимента. На его примере я буду объяснять что как работает.
Разбираем код из справки
В документации Яндекса приводится такой пример кода:
ymab('metrika.xxxx', 'getFlags', function(flags) { for (const [key, value] of Object.entries(flags)) { window.postMessage({ key, value: value[0] }, '*'); } });
Если кратко, то этот код используется для передачи флагов эксперимента в JavaScript-код сайта, в виде сообщений окну браузера. Понимаю, что все равно ничего не понятно, давайте разбирать построчно. Сначала напишу в сложном (душном) режиме, а потом то же самое опишу построчно на человекопонятном языке.
Технический разбор:
- Первая строка
ymab('metrika.xxxx', 'getFlags', function(flags) {...});
вызывает функциюymab()
из Яндекс Метрики), передавая в нее аргументы «metrika.xxxx» и «getFlags». В «metrika.xxxx» xxxx заменяется на ID вашего счетчика, а «getFlags» указывает на то, что нужно получить значения флагов экспериментов. - Вторая строка
for (const [key, value] of Object.entries(flags)) {
использует методObject.entries()
для получения списка всех ключей и значений в объектеflags
, возвращенном из Метрики. Он создает массив из пар ключ-значение объекта и возвращает его. - В третьей строке в теле цикла
for
, каждая пара ключ-значение помещается в объектwindow.postMessage()
, который отправляет сообщение в окно браузера с ключом и соответствующим значением флага.
То же самое, только простыми словами:
- В первой строчке кода мы обращаемся к Метрике и запрашиваем у нее флаги эксперимента. Вместо xxx надо написать свой номер счетчика. В ответ метрика пришлет вам список флагов в формате: { «ключ-1»: [«значение-1»], «ключ-2»: [«значение-2»]}. Важно, она пришлет не все ключи и все значения, а только для того экспериментального сегмента в который попал посетитель. К примеру, если вы попали у меня в третий сегмент, то Метрика вернет такие данные:
{ "color": [ "red" ], "content": [ "Скидка на разработку сайта - 10%" ] }
- Вторая строка кода преобразует то, что вернулось из метрики в [ «ключ-1: значение-1», «ключ-2: значение-2»].
- Третью строку никак проще не объяснишь, чем описано выше, да и по факту вам это не нужно, т.к. мне при написании статьи даже в голову не пришел сценарий, при котором человек без глубоких познаний в разработке будет использовать метод windows.postMessage(), поэтому для наглядности предлагаю заменить этот метод на console.log() и посмотреть в живую, что будет отдавать вам Метрика. Модернизированный код будет выглядеть так:
ymab('metrika.xxxx', 'getFlags', function(flags) { for (const [key, value] of Object.entries(flags)) { console.log({ key, value: value[0] }, '*'); } });
В нем мы заменили window.postMessage на console.log. Последний позволит вам посмотреть в консоли браузера, что передается из Метрики в рамках эксперимента. Естественно эксперимент уже должен быть запущен, а коды эксперимента и Метрики должны присутствовать на сайте. Так же не забудьте вместо xxx вставить ваш номер счетчика.
Копируем код и идем на тот сайт, где запущен эксперимент (или можете остаться на моем сайте и проделать то же самое). Открываем панель разработчика в браузере — в большинстве браузеров это можно сделать, нажав клавишу F12. В появившемся окне вам нужно найти консоль (console), у меня это выглядит так:
Как показано на скриншоте, вставляем внизу в поле ввода скопированный код и заменяем в нем ххх на номер счётчика (если тренируетесь на моем сайте, то вставляйте мой номер счетчика метрики — 91613465). Жмем Enter и получаем примерно такое:
Если нажать левой кнопкой мыши на один из объектов в ответе, то можно раскрыть и посмотреть его внутренности, а если нажать правой кнопкой мыши и скопировать объект, то в буфере будет такой код:
{ "key": "color", "value": "red" } { "key": "content", "value": "Скидка на разработку сайта - 10%" }
Если вам доводилось работать с ecommerce, то структура кода должна быть вам знакома. Естественно, если у себя в эксперименте вы указали другие пары ключей и значений для флагов, то метрика вернет вам ваши варианты. Данные флагов могут быть использованы в коде сайта для различных экспериментальных изменений, таких как изменение цвета кнопки или других элементов.
А теперь, когда вы понимаете как это работает, давайте реализуем эксперимент с помощью JavaScript напрямую в коде сайта и с помощью GTM.
Настраиваем эксперимент по замене цвета кнопки с помощью JS
Давайте попробуем протестировать три варианта цвета кнопки с помощью экспериментов типа «Флаги в коде». Конечно, такой же эксперимент можно провернуть и с помощью визуального редактора, но сейчас наша задача понять принцип работы, а потом будем усложнять.
Ранее в рамках эксперимента мы создали флаги с тремя цветами: red, black и green. Такие цвета поддерживаются CSS и html, а значит мы можем использовать их в коде для подмены. Кроме простых английских названий цветов можно использовать шестнадцатеричную систему задания цвета с решеткой или RGB. С помощью последних двух можно подобрать любой цвет. Вот краткая таблица палитры:
Теперь напишем скрипт, который будет менять цвет кнопки в зависимости от того, в какой экспериментальный сегмент попал пользователь.
ymab('metrika.xxxx', 'getFlags', function(flags) { const button = document.getElementById('myButton'); button.style.backgroundColor = flags.color; });
С первой строкой вы уже знакомы, она запрашивает у Метрики объект с флагами. Во второй строчке мы записываем в переменную button ссылку на элемент с id=»myButton» (это может быть любой Html элемент). В третьей строке мы дописываем к найденному элементу атрибут style со значением «background-color: значение-флага», т.е. меняем цвет фона (background) на экспериментальный из объекта флагов. У меня получилось вот так:
Вы можете заменить в этом коде xxx на свой номер счетчика, color на название своего флага, myButton на id своей кнопки и менять у себя background. Для этого вышеуказанный код нужно вставить в файл скриптов вашего сайта.
Усложним задачу.
Как мы справедливо заметили, подмену цвета можно было реализовать и с помощью эксперимента типа «Визуальный редактор». А что, если нам нужно поменять цвет заливки кнопки только тогда, когда по ней нажмут, вывести после кнопки текст с разными скидками и отправить в Метрику цель о том, что по кнопке кликнули? Вот тут без флагов ни куда. Давайте попробуем сделать.
Код будет такой (для удобства я записал комментарии непосредственно в код, они начинаются с «//»):
// Получение флагов эксперимента из Яндекс Метрики ymab('metrika.xxxx', 'getFlags', function(flags) { // запись в переменную button ссылки на элемент с id равным myButton const button = document.getElementById('myButton'); // Обработчик клика по кнопке button.addEventListener('click', function() { // Получение значения флага "color" и запись в переменную "buttonColor" const buttonColor = flags.color; // Изменение цвета кнопки button.style.backgroundColor = buttonColor; // Создаем элемент h3 с текстом из флага content и добавляем после кнопки var sale = document.createElement('h3'); sale.textContent = flags.content; button.after(sale); // Отправка события в Яндекс Метрику о смене цвета кнопки ym('metrika.xxxx', 'reachGoal', 'button_color_changed'); }); });
Код нужно вставить в файл скриптов вашего сайта или обернуть в <script></script> и добавить в подвал или шапку (лучше первый вариант). Не забываем вставить свой номер счетчика, свой ID кнопки и свои названия флагов вместо color и content.
Ниже приведена кнопка, которая работает, можете проверить в какой сегмент эксперимента попали вы. И, кстати, скидка реально действует при заказе моих услуг.
P.S. Эксперимент можно запустить максимум на год, поэтому через год кнопка перестанет работать. Если забуду перезапустить эксперимент, маякните пожалуйста любым способом и вам будет +50 к карме.
Использования «Флагов» в GTM
Да, это возможно с помощью Google Tag Manager. Самый простой способ — взять любой из скриптов выше и обернуть в <script></script>, заменить неподдерживаемый GTM синтаксис, а потом запихнуть полученный код в тег с типом «Пользовательский HTML». Связать тег с триггером «Все страницы» и все готово. Код будет выглядеть примерно так:
<script> ymab('metrika.xxxx', 'getFlags', function(flags) { var button = document.getElementById('myButton'); button.style.backgroundColor = flags.color; var sale = document.createElement('h3'); sale.textContent = flags.content; button.after(sale); }); </script>
Я взял код из предыдущего примера, но заменил const на var (т.к. GTM не поддерживает первый вариант), убрал из него прослушку клика по кнопке и отправку цели в метрику, ведь и то и другое можно сделать через GTM. Поэтому для нашего тега предлагаю создать триггер «Клик по всем элементам». Получим тот же результат, но без необходимости ковыряться в коде сайта.
Пошаговый алгоритм действий:
- создаем триггер с типом «Клик — Все элементы»;
- даем ему произвольное название;
- условие активации триггера → «Некоторые клики» → «click id» содержит «myButton».
Если у вас кнопка с другим id или классом, то цепляйтесь за свою кнопку так как считаете нужным. У меня в интерфейсе это выглядит так:
- создаем тег типа «Пользовательский HTML» и даем ему произвольное название;
- вставляем в поле ниже код из этого примера (не забываем вместо «ххх» вставить свой номер счетчика Метрики, а вместо «myButton» свой id кнопки);
- в качестве триггера активации указываем созданный ранее.
В GTM будет выглядеть так:
Если скрипт не подходит, то что в нем можно поменять?
Если у вашей кнопки нет id, но есть класс (class) и вы цепляетесь за него, тогда нужно немного модернизировать код и вместо document.getElementById(‘myButton’) написать document.getElementByClassName(‘myButton’), где вместо myButton указать css class вашей кнопки:
<script> ymab('metrika.xxxx', 'getFlags', function(flags) { var button = document.getElementByClassName('myButton'); button.style.backgroundColor = flags.color; var sale = document.createElement('h3'); sale.textContent = flags.content; button.after(sale); }); </script>
Если и с классами у вас проблема, тогда можно использовать метод document.querySelector(‘#myButton’), который также нужно вставить вместо document.getElementById(‘myButton’), но здесь в скобках придется записать более сложную конструкцию. Для этого:
- щелкните правой кнопкой мыши по элементу, цвет которого вы планируете менять и выберите пункт «Посмотреть код» или «Исследовать элемент» (зависит от браузера);
- в открывшемся окне нажмите правой кнопкой мыши на выделенный html код;
- в контекстном меню выберите «Копировать» (copy) → «Копировать селектор» (copy selector);
- вставьте скопированный селектор в наш скрипт вместо #myButton, получится примерно так:
<script> ymab('metrika.xxxx', 'getFlags', function(flags) { var button = document.querySelector('#myButton'); button.style.backgroundColor = flags.color; var sale = document.createElement('h3'); sale.textContent = flags.content; button.after(sale); }); </script>
Если у вас будут какие-то скобки, ковычки, решетки и вообще любые символы в селекторе и вы не знаете как это сокращать, лучше оставляйте как есть. Одинарные кавычки удалять нельзя. Для тех, кто хочет изучить тему селекторов глубже, я рекомендую отличную статью моего коллеги «по цеху» — Якова Осипенкова.
Так же стоит понимать, что в нашем примере button — это переменная, а не html элемент. Вы можете подвязываться к любым DOM элементам на страницах своего сайта: <div>, <h1> — <h6>, <span>, <a> и т.п. Главное, нацелиться на этот элемент по стилю, id или селектору.
В этом куске кода:
button.style.backgroundColor
вместо backgroundColor можете использовать color и тогда будет изменяться не заливка фона, а заливка текста. Так же вы можете использовать любые другие стили, т.к. свойство .style работает с html атрибутом style и туда можно поместить все что требуется. Главный принцип — если свойство с дефисом, к примеру border-radius, то дефис нужно убрать, а следующую букву сделать заглавной — borderRadius.
Если вам нужно изменить все свойств стиля элемента, можно использовать такую конструкцию (тут дефисы сохраняются):
button.style.cssText=`color: red !important; background-color: yellow; width: 100px; text-align: center; `;
Само свойство .style можно менять на другие, например на .textContent для того, чтобы поменять не стили, а контент (текст) элемента. Также вместо свойства .style можно использовать методы .after() или .before() для того, чтобы добавить что-то перед или после элемента соответственно, а также метод .append(), чтобы дописать текст в конец текущего элемента. Примеры:
var button = document.querySelector('#myButton'); button.style.backgroundColor = flags.color; //Дописываем к элементу с селектором #myButton атрибут style со значением "background-color: значение флага color" button.textContent = flags.color; // Поменяем текст кнопки на значение флага color var flagContent = flags.content; //Записываем в переменную flagContent значение флага content button.append(flagContent) //Дописываем в конец текста кнопки значение флага var sale = document.createElement('h3'); //Создаем html заголовок h3 - <h3></h3> sale.textContent = flags.content; //Записываем в созданный h3 значение флага content button.after(sale); //Вставляем после элемента с селектором #myButton, записанного в переменную button, наш заголовок h3
В этой части кода flags.color мы забираем из объекта с флагами значение флага с именем color. Если у вас флаг называется по другому, тогда вместо color пишем свое название.
И самое интересное. Вы можете создавать любые триггеры активации скрипта и у вас будут меняться условия проведения эксперимента. К примеру:
- отправлена форма со страницы регистрации — показываем эксперимент только тем, кто зарегистрировался на сайте во время проведения теста;
- файл cookie содержит запись об авторизации на сайте или отправлена форма со страницы входа в личный кабинет — показываем эксперимент только авторизованным пользователям;
- utm метка содержит «Санкт-Петербург» — показываем эксперимент только тем, кто перешел по рекламе и клик был из СПб.
Вывод:
Эксперименты типа «Флаги в коде» являются мощным инструментом, особенно в сочетании с GTM. Они помогут вам проводить практически любые тесты, которые только можно придумать на стороне сайта. Есть только два ограничения: технические знания в JavaScript и ваша фантазия. Однако не стоит экспериментировать со всем подряд, любой эксперимент должен быть обоснованным и базироваться на логической гипотезе, а так же иметь четко обозначенные качественные показатели к которым необходимо прийти.