Skip to main content

widget-utm-collector.js — сбор UTM/click-id меток для формы GetCourse

widget-utm-collector.js — сбор UTM/click-id меток в форму GetCourse

Скрипт-замена для utm_to_gk_field.js от vakas-tools. Используется в виджете формы 1602182 на странице квиза gc.fitnessmama.co/quiz.

Зачем заменили vakas

В скрипте vakas есть два критичных недостатка для нашей конфигурации:

  1. Слушает DOMContentLoaded, который к моменту загрузки виджета уже произошёл (виджет формы инжектится поздно, на email-шаге квиза). Listener регистрируется, но не срабатывает — поля остаются пустыми.
  2. Захватывает только utm_*fbclid, gclid, yclid игнорирует. Реклама без явных UTM приходит без атрибуции.
  3. Нет first-touch: при возврате на сайт по закладке или прямом заходе метки теряются.

Из-за этого в выгрузке deal_export.xlsx много сделок без меток, хотя пользователи приходили с рекламы.

Что делает новый скрипт

  1. Читает из URL: utm_source, utm_medium, utm_campaign, utm_content, utm_term, utm_group, fbclid, gclid, yclid.
  2. На первом заходе сохраняет их в localStorage (ключ fm_first_touch, срок 90 дней) — first-touch атрибуция.
  3. Если в текущем URL меток нет — подтягивает их из localStorage.
  4. Заполняет <input> и <textarea> внутри элементов формы с CSS-классами, совпадающими с именами параметров: .utm_source, .utm_group, .fbclid и т.д.
  5. Использует readyState-чек — отрабатывает даже если DOMContentLoaded уже произошёл (главный фикс).
  6. Диспатчит события input и change — нужно для корректной отправки полей GetCourse'ом.
  7. Делает три попытки заполнения (0мс, 500мс, 1500мс) — на случай поздней дорисовки виджета.

Где лежит и как подключён

Файл скрипта хостится в CMS GetCourse: https://gc.fitnessmama.co/pl/cms/layout/js?id=92493&hash=abc932387ed49dc892bf87e6f0fa586d&bundle=1

(hash пересчитывается автоматически при изменении файла — кэш сбрасывается сам.)

Подключение — в виджете формы 1602182 в HTML-блоке:

<script src="https://gc.fitnessmama.co/pl/cms/layout/js?id=92493&hash=abc932387ed49dc892bf87e6f0fa586d&bundle=1"></script>

Какие поля нужны в форме

Чтобы скрипт знал, куда писать значения, в форме виджета должны быть поля (User field или Offer field) со следующими CSS-классами:

CSS-класс Что попадёт
utm_source utm_source
utm_medium utm_medium
utm_campaign utm_campaign
utm_content utm_content
utm_term utm_term
utm_group utm_group (URL offer-страницы с ответами квиза)
fbclid Facebook click ID
gclid Google click ID
yclid Yandex click ID

Имена самих полей в GetCourse (например deal_utm_source или offer_quiz_url) — на ваше усмотрение. Важен CSS-класс на обёртке поля.

Связка со страницей квиза (quiz-pink.gc.html)

На стороне квиза работает параллельная логика в quiz-pink.gc.html:

  • INCOMING_UTM при загрузке страницы тоже захватывает все параметры из списка TRACK_PARAMS.
  • Сохраняет first-touch в тот же localStorage ключ fm_first_touch (90 дней).
  • buildOfferUrl() дописывает все эти параметры в URL формы → они доступны виджету.

Таким образом метки переживают: переходы между страницами квиза, F5, history.replaceState, возврат по закладке.

Чего скрипт НЕ решает

  • Прямой / органический / referral трафик без меток в URL и без сохранённого first-touch — нечего ловить. Это нормально, такие лиды атрибутируются как organic/direct.
  • Изменение структуры формы: если у поля в форме отсутствует CSS-класс из списка — скрипт его не заполнит. Проверяй CSS-класс при добавлении новых полей.

Как обновлять скрипт

  1. Зайти в GetCourse → CMS → найти JS-слой с id 92493.
  2. Внести правки.
  3. Сохранить — GC автоматически пересчитает hash в URL и браузеры подтянут новую версию.
  4. Если hash по какой-то причине не поменялся — добавить &v=2 в URL подключения для сброса кэша.

Как протестировать

  1. Открыть в инкогнито: https://gc.fitnessmama.co/quiz?utm_source=TEST&utm_campaign=PROOF&fbclid=ABC123
  2. F12 → Console.
  3. Пройти квиз до email-шага (быстрый jump через консоль):
    Object.assign(answers, {name:'Test', currentWeight:'70', targetWeight:'60', height:'165'});
    cur = STEPS.findIndex(s => s.type === 'email');
    render(cur, 'forward');
    
  4. Через пару секунд проверить, что скрытые поля заполнились:
    document.querySelectorAll('.utm_source input, .utm_campaign input, .fbclid input, .utm_group input, .utm_group textarea').forEach(el => {
      console.log(el.tagName, 'name=', el.name || '(no name)', 'value=', JSON.stringify(el.value));
    });
    
  5. Сабмитнуть форму. Проверить в новой сделке в GetCourse, что метки записались в соответствующие поля.

Что делать, если метки не пишутся

  1. Проверить, что скрипт загружен: в Network найти запрос pl/cms/layout/js?id=92493 — статус 200, в Response виден код.
  2. Проверить first-touch в localStorage: в Console → localStorage.getItem('fm_first_touch') — должен быть JSON с ts и data.
  3. Проверить наличие полей с нужными классами: в Console → document.querySelectorAll('.utm_source, .utm_group').length — больше 0.
  4. Проверить, что класс стоит на правильном элементе: класс должен быть на обёртке поля (Offer field / User field в билдере GC), а внутри неё уже находится <input> или <textarea>.

История изменений

  • 2026-05-18 — первая версия. Замена vakas-tools/utm_to_gk_field.js.
    • Добавлен readyState-чек.
    • Добавлена поддержка fbclid/gclid/yclid.
    • Добавлен first-touch на 90 дней в localStorage.
    • Заполнение <textarea> в дополнение к <input> (для длинных полей вроде offer_quiz_url).
    • Диспатч событий input/change после установки значения.