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 есть два критичных недостатка для нашей конфигурации:
- Слушает
DOMContentLoaded, который к моменту загрузки виджета уже произошёл (виджет формы инжектится поздно, на email-шаге квиза). Listener регистрируется, но не срабатывает — поля остаются пустыми. - Захватывает только
utm_*—fbclid,gclid,yclidигнорирует. Реклама без явных UTM приходит без атрибуции. - Нет first-touch: при возврате на сайт по закладке или прямом заходе метки теряются.
Из-за этого в выгрузке deal_export.xlsx много сделок без меток, хотя пользователи приходили с рекламы.
Что делает новый скрипт
- Читает из URL:
utm_source,utm_medium,utm_campaign,utm_content,utm_term,utm_group,fbclid,gclid,yclid. - На первом заходе сохраняет их в
localStorage(ключfm_first_touch, срок 90 дней) — first-touch атрибуция. - Если в текущем URL меток нет — подтягивает их из
localStorage. - Заполняет
<input>и<textarea>внутри элементов формы с CSS-классами, совпадающими с именами параметров:.utm_source,.utm_group,.fbclidи т.д. - Использует
readyState-чек — отрабатывает даже еслиDOMContentLoadedуже произошёл (главный фикс). - Диспатчит события
inputиchange— нужно для корректной отправки полей GetCourse'ом. - Делает три попытки заполнения (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-класс при добавлении новых полей.
Как обновлять скрипт
- Зайти в GetCourse → CMS → найти JS-слой с id 92493.
- Внести правки.
- Сохранить — GC автоматически пересчитает
hashв URL и браузеры подтянут новую версию. - Если
hashпо какой-то причине не поменялся — добавить&v=2в URL подключения для сброса кэша.
Как протестировать
- Открыть в инкогнито:
https://gc.fitnessmama.co/quiz?utm_source=TEST&utm_campaign=PROOF&fbclid=ABC123 - F12 → Console.
- Пройти квиз до email-шага (быстрый jump через консоль):
Object.assign(answers, {name:'Test', currentWeight:'70', targetWeight:'60', height:'165'}); cur = STEPS.findIndex(s => s.type === 'email'); render(cur, 'forward'); - Через пару секунд проверить, что скрытые поля заполнились:
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)); }); - Сабмитнуть форму. Проверить в новой сделке в GetCourse, что метки записались в соответствующие поля.
Что делать, если метки не пишутся
- Проверить, что скрипт загружен: в Network найти запрос
pl/cms/layout/js?id=92493— статус 200, в Response виден код. - Проверить first-touch в localStorage: в Console →
localStorage.getItem('fm_first_touch')— должен быть JSON сtsиdata. - Проверить наличие полей с нужными классами: в Console →
document.querySelectorAll('.utm_source, .utm_group').length— больше 0. - Проверить, что класс стоит на правильном элементе: класс должен быть на обёртке поля (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после установки значения.