Apple против Google Analytics и Яндекс.Метрики. Клиентские куки теперь живут в Safari до 7 дней. Гайд о том, как с этим бороться.

Тихо и незаметно подкрадывается маленький пушной зверек к привычной нам веб-аналитике. К примеру, 21 февраля 2019 года вышла новая версия «Умной защиты от трекинга» версии 2.1 (ITP 2.1) в которой куки, установленные на клиенте, теперь будут жить в Safari не больше 7 дней. Это куки Google Analytics, Яндекс.Метрики, Facebook и прочих систем аналитики.

Что это вообще значит?

Раньше практически все системы аналитики помечали пользователя на сайте, чтобы, к примеру, понять, что через 2 недели это он же вернулся на сайт, а не кто-то новый.

При первом заходе на сайт в куки на года 2 сохранялся сгенерированный ClientID. И когда человек возвращался через месяца 3, система аналитики «видела», что куки уже есть и связывала этого этот заход на сайт с тем же пользователем.

Сейчас же определить, что это тот же человек зашел на сайт, если он пользуется Safari, можно будет только в течение 7 дней.

Доказательство:

Зашел посмотреть куки своего блога через Safari в момент написания статьи. В столбце даты у куки _ga должно быть 2 года, а сейчас 7 дней 🙂 В хроме все хорошо

А если я хочу отслеживать пользователей дольше 7 дней?

Можно сохранять ClientID где-то в браузере, где его пока не удаляют 🙂 К примеру, в localStorage. Пока что его в ITP не забанили.

Что это такое? Если кратко, это что-то, похожее на куки, только хранится в браузере «вечно». И доступ к этому есть, в отличие от кук, только из этого браузера. Со стороны сервера localStorage недоступен, ибо не отправляется на сервер из браузер вместе с запросом при каждом открытии страницы или подгрузке картинки.

Гайд о том, как это сделать за меня уже написал легендарный Simo Ahava здесь. Я постарался описать это на русском кратко, понятно и со скринами.

1) Создать в Google Tag Manager переменную, которая будет доставать ClientID из localStorage и класть в Google Analytics

Первый кусок кода, который достает ClientID из localStorage и кладет в Google Analytics:

function() {
  var objectName = 'ga_client_id';
  if (window.localStorage) {
    var jsonObj = window.localStorage.getItem(objectName) || '{}';
    var obj = JSON.parse(jsonObj);
    var now = new Date().getTime();
    if (obj.clientId && obj.expires) {
      if (now <= obj.expires) {
        return obj.clientId;
      }
    }
  }
  return;
}

Теперь куда его деть:

Заходим в GTM раздел «Переменные» и создаем пользовательскую переменную
Называем переменную «clientIdFromLocalStorage» и выбираем тип «Собственный код JavaScript»
Вставляем код выше и сохраняем

2) Создать в Google Tag Manager переменную, которая будет класть ClientID в localStorage

Это делается АБСОЛЮТНО так же, как в 1-м пункте, различия только будут в названии переменной и коде:

  1. Название: «clientIdToLocalStorage»
  2. Код будет ниже. Здесь Simo Ahava немного перемудрил и перестраховался. Я ненужное вырезал, нужное оставил. Авторские комментарии сохранены 🙂
function () {
  // customTask Builder by Simo Ahava
  //
  // More information about customTask: https://www.simoahava.com/analytics/customtask-the-guide/
  //
  // Change the default values for the settings below.

  // localStorageCid: Use localStorage to persist Client ID with Google Analytics tags
  // https://bit.ly/2GNElc4
  var localStorageCid = {
    objectName: 'ga_client_id',
    expires: 1000*60*60*24*365*2
  };

  // DO NOT EDIT ANYTHING BELOW THIS LINE
  var globalSendHitTaskName   = '_ga_originalSendHitTask';

  return function (customTaskModel) {

    window[globalSendHitTaskName] = window[globalSendHitTaskName] || customTaskModel.get('sendHitTask');

    // localStorageCid
    if (typeof localStorageCid === 'object' && typeof localStorageCid.objectName === 'string' && typeof localStorageCid.expires === 'number' && window.Storage) {
      var _lsc_clientId = customTaskModel.get('clientId');
      var _lsc_obj = JSON.stringify({
        clientId: _lsc_clientId,
        expires: new Date().getTime() + localStorageCid.expires
      });
      window.localStorage.setItem(localStorageCid.objectName, _lsc_obj);
    }
    // /localStorageCid

    customTaskModel.set('sendHitTask', function (sendHitTaskModel) {

      var originalSendHitTaskModel = sendHitTaskModel,
          originalSendHitTask      = window[globalSendHitTaskName],
          canSendHit               = true;

      try {

        if (canSendHit) {
          originalSendHitTask(sendHitTaskModel);
        }

      } catch(err) {
        originalSendHitTask(originalSendHitTaskModel);
      }

    });

  };
}

3) Запустить функции, которые хранятся в переменных

Открываем настройки тега Google Analytics и добавляем в «Дополнительные настройки» -> «Поля, которые необходимо задать» наши переменные как на скрине:

Главное, не перепутайте, местами, что и куда 🙂

Важный момент: если названия переменных, которые мы создали в пунктах 1 и 2 еще можно менять, то в пункте 3 «Название поля» должно быть именно таким:

  • clientId — первое поле, собственно в эту переменную будет возвращаться из localStorage clientId если он там есть
  • customTask — второе поле, в это поле будет возвращаться не значение, а функция, которая выполнится перед отправкой данных в Google Analytics. Эта функция, как раз, сохраняет clientId в localStorage.

Если вы все правильно сделали и опубликовали изменения, то у вас появится новое поле в localStorage:

Если у вас появилось это, то все заработало как надо

Если есть вопросы, идеи, пожелания или предложения, пишите в комментариях

Алексей Ярошенко

Интернет-маркетолог. Сертифицированный специалист по Google AdWords, Google Analytics и Яндекс.Директ. Сертифицированный тренер Google в Беларуси.