Вот некоторые из вещей, которые мы реализовали в недавнем обновлении нашей реализации GTM, и мы думаем, что им стоит поделиться.

Отделение GTM от приложения

Вся цель GTM - отделить проблемы отслеживания от проблем вашего приложения. Вместо того, чтобы добавлять push-уведомления о событиях для каждой отдельной библиотеки отслеживания (например, gaq, fbq, snaptr,…), вы отправляете пользовательские события в уровень данных GTM, а затем настраиваете GTM для выполнения всего остального.

Это означает, что изменения в реализации отслеживания (например, добавление нового поставщика услуг онлайн-маркетинга) могут быть выполнены без изменения кода вашего приложения и без привлечения ваших разработчиков (при условии, что ваши аналитики данных обладают необходимыми навыками для поддержки реализации GTM самостоятельно).

(Старый) сквозной подход

Часто вы обнаруживаете, что ваша компания некоторое время назад перешла с нативной - скорее всего, ориентированной на Google Analytics - отслеживания на GTM. Из-за типичных временных ограничений такой миграции и / или отсутствия полного понимания возможностей GTM во время этих усилий обычным явлением является реализация, основанная на сквозных событиях.

Это в основном означает, что вы все еще реализуете большую часть логики отслеживания в своем приложении, чтобы затем отправлять события, ориентированные на GA, которые содержат данные в формате GA в ваших push-уведомлениях dataLayer. У вас будет только один тип событий для ваших push-уведомлений GTM, а может быть, два (в нашем случае у нас были ga.event и ga.ec.event). Ваша реализация GTM (по крайней мере, теги, связанные с GA) сравнительно тонкая. GTM просто передает данные о событии в GA.

При переходе от реализации прямого отслеживания, ориентированного на GA, это требует наименьших усилий для настройки. И это тот путь, по которому мы изначально пошли.

Проходят годы, и на первый взгляд это может прекрасно сработать для вас. Вы возвращаетесь через 2 года назад, исследуете все теги в GTM и понимаете, что люди добавляли всевозможные другие теги: пиксели Facebook, пиксели Twitter, 20 различных пикселей отслеживания конверсий, реализацию снегоочистителя и многое другое. И вы замечаете, что все эти теги, или, по крайней мере, те, которые имеют дело с данными о продуктах или конверсиях, реализовали акробатические способы разнообразить одно или два ваших события и переформатировать данные, ориентированные на GA, которые вы поместили в уровень данных, в то, что они на самом деле нужно. Вы также можете обнаружить, что некоторые из них реализовали дополнительные push-уведомления dataLayer для получения данных, которые не включены в модель расширенной электронной торговли GA.

Ваш код GTM и dataLayer превратились в гигантский конгломерат исправлений. Ваши теги, ориентированные на GA, очень тонкие, но все остальное без необходимости выдувается, потому что необходимо обойти тот факт, что данные, которые вы отправляете в dataLayer, и способ, которым вы их отправляете, адаптированы только для GA и GA. .

Разнообразные мероприятия

Чтобы решить эти проблемы, мы отказались от двух «общих» ga-событий и реализовали новую схему именования событий на основе семантического пути. Вот несколько примеров новых событий, которые наш интерфейс программно отправляет в dataLayer:

  • ti.search.suggestion
  • ti.checkout.step
  • ti.facet.filter
  • ti.newsletter.subscribe

и так далее. Схема такая….

<namespace>.<category>[.<category>….].<action>

Список категорий произвольный, но от менее конкретных к более конкретным (слева направо). Категории и действие не следует путать с категорией событий и действием GA. Здесь мы просто говорим об идентификаторах типов событий.

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

  • ti\.search\..+
  • ti\.[^.]+\.subscribe
  • ti\..*(popup).*\.(show|hide)

Это позволяет вам легко определять белые и черные списки для триггеров событий, где с помощью общих сквозных событий ga.event вам нужно было реализовать дополнительную логику, чтобы определить, что на самом деле произошло, и должен ли ваш тег OM срабатывать в этом конкретном случае.

Общие данные о событиях

Каждое из этих настраиваемых событий несет в себе некоторые данные о событиях, которые мы помещаем в объект eventData на уровне данных. Соответствующая переменная dataLayer в GTM установлена ​​как переменная V1, которая гарантирует, что весь объект заменяется - а не объединяется - для каждого нового события, отправляемого из приложения.

Для удобства и поскольку это полезно не только для GA, eventData содержит три стандартных свойства category, action и label, а наши теги GA настроены для сопоставления их с соответствующими свойствами GA.

Но eventData также может содержать дополнительные произвольные данные, например для поиска по сайту мы помещаем поисковый запрос в eventData.term и так далее. Опять же, эти свойства устанавливаются в соответствии с семантикой приложения (например, имеет смысл подтолкнуть условие поиска с событием отслеживания поиска), а не в соответствии с тем, что требуется конкретному провайдеру отслеживания в их формате. Если конкретный тег использует или нет, то эта информация полностью контролируется внутри GTM, а не приложениями.

Все это событие

В нашей первоначальной реализации мы объявили объект dataLayer со всеми начальными данными перед включением тега embed. В нашей новой реализации мы следуем совету Симо Ахава вместо этого отправляйте все данные.

Мы идем еще дальше и делаем каждый из этих подталкиваний событием, каждый раз прикрепляя свойство события. Мы зарезервировали специальный префикс пути к точке ti.data. имени события для этих простых событий передачи данных. Хотя мы обычно не рекомендуем прикреплять триггеры к этим событиям - поскольку нет гарантии, что другие данные, которые могут понадобиться тегам, уже будут заполнены при срабатывании любого из них, - это может оказаться полезным для отладки и самоанализа.

Это также означает, что вместо создания одного гигантского блока данных мы теперь можем заполнить наш dataLayer значимыми фрагментами, такими как ti.data.page, ti.data.user, ti.data.device и так далее.

Однонаправленный поток данных

В нашей старой реализации мы помещали свойства в уровень данных, а затем пытались прочитать их снова. Это особенно верно для данных о продуктах и ​​агрегированных списков данных о продуктах, которые были отправлены на уровень данных в предварительно отформатированном виде. Когда в интерфейс поступало больше данных через AJAX из API, возникла необходимость прочитать эти списки, повторно проанализировать их, добавить в них новые записи и отправить их обратно в уровень данных, оставив у нас чувство неловкости. , не говоря уже о кучке довольно не элегантного кода приложения.

В нашей новой реализации мы позаботились о том, чтобы никогда не приходилось считывать данные из уровня данных. Все данные, в частности данные о продуктах, помещаются в стандартный формат и аддитивным образом в уровень данных, и мы реализовали функции агрегирования в пользовательских переменных JavaScript, которые могут извлекать списки отдельных значений и тому подобное.

Вот пример (мы назвали его fn.extract-values):

function () {
  return function (collection, property) {
    var results = [],
        i = 0,
        product;
  
    for (; item = collection[i]; i++) {
        if (!item[property]) {
            continue;
        }
        
        results.push(item[property]);
    }
  
    return results;
  }
}

Теперь мы можем использовать это, например, для создания списка названий продуктов, разделенных запятыми - либо непосредственно в пользовательском теге HTML, либо в другой пользовательской переменной JavaScript:

{{fn.extract-values}}({{cart.products}}, 'name').join(',');

С помощью вышеупомянутых более разнообразных событий и таких функций агрегации мы также избавились от любой необходимости передавать данные на уровень данных изнутри уровня данных или от любых подобных уловок.

Теперь существует односторонний поток данных от приложения к уровню данных через переменные в теги.

Переменные уровня данных V2

Мы обновили все переменные dataLayer до V2, за исключением упомянутой выше переменной eventData. Это позволяет нам объединять дополнительные данные в иерархические объекты данных или списки, что может стать особенно удобным, если дополнительные данные поступают через запросы AJAX.

Сброс любого из них можно выполнить, изменив их тип, например, путем нажатия пустой строки для записи user и последующего нажатия нового объекта user.

Точка-путь Имена переменных

Как и в случае с событиями, мы изменили наше соглашение об именах для переменных GTM на точечный подход. Это означает, что любые переменные уровня данных напрямую напоминают точечный путь, который соответствует базовой структуре объекта. Например. переменная page.type указывает на свойство type объекта page, помещенного в уровень данных.

К другим переменным добавляется префикс сегмента точки-пути, который указывает на их природу, например Пользовательские переменные JavaScript, содержащие вспомогательные функции, имеют префикс fn., переменные поиска часто имеют префикс lookup., переменные, извлекающие данные из URL-адреса, начинаются с url. и так далее.

Это группирует связанные переменные вместе в отсортированном по алфавиту списке в GTM и упрощает «угадывание» имен переменных при назначении их тегам, даже не просматривая список переменных.

Поля поиска

Функция, которую легко не использовать в GTM, - это переменные поиска. Например. для некоторых поставщиков Custom OM у нас был реализован ряд различных настраиваемых тегов HTML, которые все делали одно и то же с вариацией одного значения и были связаны с триггерами разных типов страниц.

Эффективное использование переменных поиска позволило нам свести их к одному тегу с несколькими триггерами и переменной поиска, которая диверсифицировала значение на основе нашей переменной page.type dataLayer. Меньше дублирования, лучше ремонтопригодность.

В некоторых случаях необходимо было диверсифицировать по типу страницы в большинстве случаев, но по типу события в других случаях. Эту проблему можно решить, используя вторую поисковую переменную вместо значения первой по умолчанию. Если вы знакомы с основными концепциями программирования, представьте, что это два вложенных оператора switch, один из которых обрабатывает регистр по умолчанию, а другой.

Пользовательские переменные Javascript

Это одна из самых мощных функций GTM. По общему признанию, они перенесут вас в пространство, где вам потребуется, чтобы ваши аналитики данных приобрели некоторые навыки программирования. Но это же хорошо, правда?

Мы совсем недавно рассмотрели видный пример их использования, но мы также используем их, в частности, для агрегатных функций, которые позволяют нам загружать стандартизованные данные в GTM, а затем переформатировать эти данные в соответствии с потребностями отдельного поставщика услуг отслеживания.

Отслеживание расширенной электронной торговли

Не вдаваясь в подробности этого вопроса, вам действительно следует последовать совету Симо, чтобы обойти встроенную переменную электронной коммерции и вместо этого использовать пользовательскую переменную JavaScript.

Как упоминалось выше, в прошлом мы предварительно отформатировали все, в частности данные электронной торговли - это в основном данные о товарах - специфичным для GA способом и поместили их в свойство электронной торговли на уровне данных.

Как только вы переключитесь на пользовательскую переменную JavaScript, которая извлекает формат, специфичный для GA-EE, из более общих и более богатых сообщений, вы удивитесь, почему Google даже встроил это свойство по умолчанию в GTM.

Прямо сейчас мы помещаем данные о товарах в dataLayer тремя разными способами:

  • У нас есть глобальный products магазин, в котором хранятся основные данные о продуктах, настолько богатые, насколько это необходимо для любых задач отслеживания. Это включает в себя имена, категоризацию и информацию о ценах, чтобы упомянуть несколько.
  • Мы помещаем отдельные списки продуктов, в основном их идентификаторы, в отдельные списки, например, cart.products, catalog.products или wishlist.products и т. Д. Обычно они содержат варианты, количества и при необходимости переопределения цен.
  • И затем у нас есть события, содержащие списки продуктов в свойстве eventData.products, которые фактически содержат продукты, относящиеся к этому событию (например, события пакетных показов, события добавления в корзину и т. Д.). Опять же, они содержат переопределения по мере необходимости, в зависимости от контекста.

У нас есть агрегированные функции, закодированные в пользовательских переменных Javascript в нашей реализации GTM, которые могут объединять их и переформатировать в формат, необходимый для отслеживания расширенной электронной торговли GA. Но они также могут переформатировать их в формат, требуемый пикселями Facebook и т. Д. В нашей настройке около 6 таких переменных вспомогательных функций, и они подходят для всего множества поставщиков BI / OM, которые мы используем.

Эта реализация уже зарекомендовала себя как более мощная (теперь мы можем поддерживать несколько списков продуктов на странице, тогда как раньше мы были ограничены одним списком на страницу) и более стабильная, чем наше предыдущее предварительно отформатированное решение на стороне приложения.

По сути…

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

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

Если вам понравилась эта статья, дайте нам CLAP (или 50!) ниже и обязательно подпишитесь на публикацию THE ICONIC Tech!