Посетитель пришёл по рекламе, в адресе страницы стояли UTM-метки, а в письме с заявкой их нет. Метки никуда не исчезли: они остались в адресе первой страницы, а форму человек отправил с третьей. Чтобы метки доехали до заявки, их нужно запомнить в начале визита и передать вместе с формой. Разберём, как это сделать.
Зачем нужны UTM-метки в самой заявке
Метрика и другие счётчики и так показывают источники визитов. Но счётчик отвечает на вопрос «откуда пришли посетители», а не «откуда пришёл вот этот клиент». Когда метки лежат в заявке, их видит менеджер, они попадают в CRM и в выгрузку, и по ним можно посчитать заявки и продажи по каждой кампании, объявлению и ключевой фразе.
Есть и вторая причина. Счётчик работает в браузере, и часть посетителей он не видит: блокировщики рекламы, ошибки скриптов, оборванная связь. Метки в заявке не зависят от того, сработала ли цель в Метрике. Почему цифры счётчика и реальные заявки расходятся, разобрано в статье «Почему заявки в Метрике не совпадают с CRM и почтой».
Какие метки бывают и что в них писать
Стандартных UTM-меток пять. Обязательных среди них нет, но без первых трёх отчёт по источникам почти бесполезен.
| Метка | Что означает | Пример |
|---|---|---|
| utm_source | источник трафика: рекламная система, сайт, рассылка | yandex, vk, newsletter |
| utm_medium | тип трафика | cpc, email, social |
| utm_campaign | кампания | spring_sale или номер кампании |
| utm_term | ключевая фраза или аудитория | купить диван |
| utm_content | объявление или вариант креатива | banner_red |
Главное правило разметки: одинаковые вещи всегда называть одинаково. Если в одной кампании стоит
utm_source=yandex, а в другой Yandex или ya, в выгрузке это будут три разных
источника, и их придётся склеивать вручную. Договоритесь о словаре значений и держите его в одном месте.
Почему метки теряются к моменту отправки формы
UTM-метки живут в адресе страницы: ?utm_source=yandex&utm_medium=cpc&utm_campaign=spring.
Их видит только первая страница визита. Дальше человек кликает по меню, и в адресах следующих страниц меток уже нет.
Если форма стоит на странице «Контакты», а скрипт формы берёт метки из текущего адреса, он ничего не найдёт.
Метки теряются и раньше, ещё до первой страницы:
- Редирект без параметров. Сайт перенаправляет с
httpнаhttps, с адреса без слэша на адрес со слэшем или сwwwна домен без него и при этом отбрасывает строку запроса. - Короткие ссылки и промежуточные страницы. Сервис сокращения ссылок или страница согласия пересобирает адрес и выкидывает метки.
- Ошибка в разметке ссылки. Два знака вопроса, пробел в значении, метка после символа
#. Всё, что стоит после#, браузер на сервер не отправляет вовсе.
Поэтому первое правило: метки нужно сохранить на первой странице визита, сразу, а не искать их в момент отправки формы. Сделать это можно в браузере или на сервере.
Способ 1. Скрытые поля и JavaScript
Самый распространённый вариант. Небольшой скрипт на каждой странице сайта смотрит, есть ли в адресе метки, и если есть, запоминает их в браузере. Второй скрипт перед отправкой подставляет сохранённые значения в скрытые поля формы. Метки уходят вместе с именем и телефоном, как обычные поля.
Шаг 1. Сохранить метки при входе на сайт
Этот код ставится в общий шаблон сайта, чтобы он выполнялся на любой странице, на которую может прийти посетитель:
<script>
(function () {
var keys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
var params = new URLSearchParams(location.search);
var found = {};
keys.forEach(function (k) {
if (params.get(k)) { found[k] = params.get(k); }
});
// Пришли по ссылке с метками: запоминаем их и страницу входа.
// Пришли без меток: ничего не трогаем, сохранённые остаются.
if (Object.keys(found).length) {
try {
localStorage.setItem('utm', JSON.stringify({ t: Date.now(), v: found, page: location.href }));
} catch (e) {}
}
})();
</script>
Обратите внимание на условие: метки перезаписываются, только если человек пришёл по ссылке с метками. Если он вернулся на сайт из закладки или ввёл адрес вручную, сохранённые метки прошлого визита остаются. Это модель «последний переход с метками». Если вам важен самый первый источник клиента, сохраняйте метки, только когда в хранилище ещё пусто.
Шаг 2. Добавить скрытые поля в форму
В каждую форму, по которой нужно знать источник, добавьте скрытые поля с именами меток. Отдельное поле для страницы входа не обязательно, но полезно: по нему видно, на какую посадочную страницу пришёл человек.
<form action="/send.php" method="post">
<input type="text" name="name" placeholder="Имя">
<input type="tel" name="phone" placeholder="Телефон">
<input type="hidden" name="utm_source">
<input type="hidden" name="utm_medium">
<input type="hidden" name="utm_campaign">
<input type="hidden" name="utm_term">
<input type="hidden" name="utm_content">
<input type="hidden" name="start_page">
<button type="submit">Отправить</button>
</form>
Шаг 3. Подставить значения перед отправкой
Скрипт заполняет скрытые поля всех форм на странице сохранёнными значениями:
<script>
document.addEventListener('DOMContentLoaded', function () {
var saved = null;
try { saved = JSON.parse(localStorage.getItem('utm') || 'null'); } catch (e) {}
// Метки старше 30 дней считаем устаревшими.
if (!saved || Date.now() - saved.t > 30 * 24 * 3600 * 1000) { return; }
document.querySelectorAll('form input[type="hidden"]').forEach(function (input) {
if (input.name === 'start_page') { input.value = saved.page || ''; }
else if (saved.v[input.name]) { input.value = saved.v[input.name]; }
});
});
</script>
Если формы появляются на странице позже, например во всплывающем окне или в квизе, заполнять поля нужно в момент открытия окна или перед отправкой, а не только при загрузке страницы.
Шаг 4. Принять метки на сервере
Обработчик формы получит метки как обычные поля utm_source, utm_medium и так далее.
Их нужно явно добавить в письмо о заявке, в запись в базе или в передачу в CRM. Частая ошибка: скрытые поля
в форме есть и заполняются, но шаблон письма их не выводит, и менеджер меток не видит.
Плюсы и минусы способа
- Работает на любой платформе: конструкторы сайтов, CMS, самописные сайты. Многие конструкторы умеют подставлять метки в скрытые поля сами, нужно лишь включить это в настройках формы.
- Зависит от JavaScript. Если скрипт не загрузился или на странице упал чужой код, поля останутся пустыми, а форма уйдёт без меток.
- Хранилище браузера живёт на одном устройстве. Пришёл с телефона, а заявку отправил с ноутбука: меток не будет. Это ограничение любого способа, не только этого.
- Каждую новую форму нужно не забыть дополнить скрытыми полями.
Способ 2. Сессия на сервере
Второй вариант не зависит от скриптов в браузере. Сервер сайта на первом запросе визита запоминает адрес страницы входа и реферер в сессии, а при отправке формы берёт их оттуда. Метки разбираются из сохранённого адреса.
<?php
session_start();
// Первый хит визита: запоминаем адрес страницы входа целиком, метки в нём.
if (!isset($_SESSION['start_url'])) {
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$_SESSION['start_url'] = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$_SESSION['referer'] = $_SERVER['HTTP_REFERER'] ?? '';
}
// В обработчике формы:
$query = parse_url($_SESSION['start_url'] ?? '', PHP_URL_QUERY) ?: '';
parse_str($query, $params);
$utmSource = $params['utm_source'] ?? '';
$utmCampaign = $params['utm_campaign'] ?? '';
Код подходит для сайтов на PHP. В других языках принцип тот же: у любого веб-фреймворка есть сессии. Для сайтов на WordPress с Contact Form 7 и на 1С-Битрикс эта схема уже расписана готовыми решениями: плагин для Contact Form 7 и обработчик для веб-форм Битрикса.
Плюсы и минусы способа
- Не зависит от JavaScript и блокировщиков: адрес и реферер сервер получает в самом запросе.
- Формы менять не нужно: источник добавляется в заявку в обработчике, для всех форм сразу.
- Первая страница визита должна обрабатываться сервером. Если страницу отдаёт полный кеш, CDN или статический HTML, сессия не запустится, и источник не сохранится.
- Сервер не видит часть адреса после
#. Если метки или важные параметры стоят там, их придётся передавать из браузера, как описано в инструкции про URL входа с якорем. - Сессия обычно живёт до закрытия браузера. Если человек вернулся завтра, источником станет новый визит.
Какой способ выбрать
| Скрытые поля и JavaScript | Сессия на сервере | |
|---|---|---|
| Нужен ли доступ к серверу | нет, хватает шаблона страницы | да, правка обработчика и шаблона |
| Блокировщики и ошибки скриптов | могут оставить поля пустыми | не влияют |
| Страницы из полного кеша | работает | источник не сохранится |
| Часть адреса после # | видна | не видна |
| Новые формы | каждую дополнить полями | подхватываются сразу |
| Повторный визит через несколько дней | метки хранятся, сколько задано | обычно нет |
На конструкторах сайтов, где обработчик формы недоступен, остаётся первый способ. На своём сервере надёжнее второй,
а для страниц с # в адресе их совмещают: сервер хранит адрес и реферер, а скрипт дописывает полный
адрес из браузера.
Как проверить, что метки доходят до заявки
- Откройте сайт по ссылке с тестовыми метками, например
?utm_source=test&utm_campaign=check, в окне браузера без расширений. - Перейдите по меню на две-три другие страницы, как сделал бы обычный посетитель.
- На странице с формой откройте инструменты разработчика и посмотрите скрытые поля: в них должны стоять значения test и check. Для первого способа видно и сохранённую запись в хранилище браузера.
- Отправьте форму и найдите заявку там, где её видит менеджер: в письме, в CRM или в журнале заявок. Метки должны быть и там.
- Повторите проверку с телефона и в браузере с блокировщиком рекламы.
Проверку стоит повторять после каждого обновления сайта, смены шаблона или формы: именно тогда метки чаще всего и перестают доходить.
Ошибки, из-за которых метки всё равно теряются
- Метки перезаписываются на каждой странице. Скрипт сохраняет «текущие метки» на каждой странице, и на второй странице пустые значения затирают настоящие.
- Метки берутся из текущего адреса формы. Работает, только если форма стоит на странице входа.
- Значения не декодируются. Кириллица в метке приходит как
%D0%B2%D0%B5%D1%81%D0%BD%D0%B0.URLSearchParamsв браузере иparse_strв PHP декодируют значения сами, ручной разбор строки обычно нет. - Метки поставлены не во все объявления. Тогда у части заявок источник пуст, и в отчёте они выглядят как «прямые заходы». Проверьте ссылки во всех кампаниях, включая архивные объявления, которые ещё показываются.
- Скрытые поля есть, но не уходят дальше. Метки дошли до сервера, но их нет в письме и в CRM: обработчик их просто не передаёт.
Как метки передаются в Linkodium Analytics
Linkodium Analytics хранит каждую заявку вместе со страницей входа, реферером и пятью UTM-метками. Отдельно
передавать метки не нужно: сервис сам разбирает utm_source, utm_medium,
utm_campaign, utm_term и utm_content из адреса страницы входа.
Важно: поля с именами utm_source и другими API приёма заявок как отдельные поля не принимает.
Передавайте полный адрес первой страницы визита в поле start_url, а адрес, полученный в браузере,
в start_url_js. Если заполнены оба, метки берутся из start_url_js. Все поля перечислены
в инструкции «Передача данных».
Если сайт на WordPress с Contact Form 7, ничего писать не нужно: плагин сам запоминает страницу входа в сессии и передаёт её с заявкой. В кабинете метки видны в карточке заявки и в выгрузке в Excel, каждая в своём столбце. Сервис бесплатный, число сайтов и заявок не ограничено.