Рекламная ссылка содержит utm_source, utm_medium и utm_campaign, но в отчёте появляется прямой или неопределённый трафик. Начните с самого URL: пройдите каждый редирект и найдите первый ответ, в котором исчезла строка запроса. Так разработчик получит конкретный адрес и заголовок Location, а маркетолог не будет ждать новые визиты ради проверки очевидной потери.
Ниже — проверка одной цепочки до открытия отчётов GA4 или Метрики. Она показывает, где сервер сохранил метки, где изменил их и где удалил.
Почему метки теряются на редиректе
UTM передаются как параметры URL. Google Analytics читает их из целевого адреса и использует в отчётах о привлечении. Рекламные идентификаторы работают похожим образом: Google Ads добавляет gclid, а Директ — yclid. Официальные справки обеих платформ требуют, чтобы сайт корректно открывал такие ссылки и передавал идентификатор до конечной страницы.
При HTTP-редиректе сервер возвращает статус 3xx и заголовок Location. HTTP Semantics RFC 9110 определяет перенаправление через значение Location: именно оно задаёт следующий URL. Если приложение собирает новый адрес только из пути и забывает исходную строку запроса, браузер послушно переходит уже без меток. Код 301 или 302 сам по себе ничего не сохраняет.
Типичная цепочка выглядит так:
- рекламная ссылка ведёт на сокращатель или трекер;
- трекер перенаправляет на промежуточный адрес;
- сайт переводит пользователя на канонический домен, язык или страницу;
- счётчик аналитики загружается на конечной странице.
Проверять стоит каждый переход. Финальный URL без UTM подтверждает потерю, но не показывает виноватый редирект.
Учебный пример
Возьмём условную ссылку:
https://shop.example/start?utm_source=partner_digest&utm_medium=email&utm_campaign=october_testПервый ответ ведёт на /tracker и переносит всю строку запроса. Второй отправляет на /landing без параметров. Проблема возникает между трекером и посадочной страницей.
Первая потеря видна во втором Location: исходные параметры были на входе и отсутствуют в следующем URL.
Для проверки рабочего сайта используйте отдельные тестовые значения, которые легко исключить из отчёта. Не помещайте в URL имя, телефон, email и другие персональные данные. Ссылку проверяйте только на своём ресурсе или с разрешения владельца.
Сохраните всю цепочку через curl
Команда ниже следует по редиректам, записывает все полученные заголовки и не сохраняет тело страницы. В macOS и большинстве дистрибутивов Linux curl обычно уже установлен; в Windows доступность зависит от версии и окружения.
curl --silent --show-error --location --max-redirs 10 \
--dump-header redirect-headers.txt \
--output /dev/null \
'https://shop.example/start?utm_source=partner_digest&utm_medium=email&utm_campaign=october_test'Откройте redirect-headers.txt. Каждый блок начинается со статуса ответа. Для редиректа найдите Location и сравните параметры с предыдущим URL:
HTTP/2 302
location: https://shop.example/tracker?utm_source=partner_digest&utm_medium=email&utm_campaign=october_test
HTTP/2 302
location: https://shop.example/landing
HTTP/2 200В этом примере первый переход получает статус OK, второй — LOST. Если значение осталось, но изменилось, фиксируйте CHANGED. Например, utm_source=telegram и utm_source=Telegram могут стать разными строками в отчёте.
Что записать в таблицу
| Переход | Статус | URL до | URL после | Результат |
|---|---|---|---|---|
| 1 | 302 | /start + 3 UTM | /tracker + 3 UTM | OK |
| 2 | 302 | /tracker + 3 UTM | /landing | LOST: 3 UTM |
| 3 | 200 | /landing | /landing | Конечная страница |
Для массовой приёмки добавьте отдельные колонки для utm_source, utm_medium, utm_campaign, gclid и yclid. Значение не применимо безопаснее пустой ячейки: оно показывает, что параметр отсутствовал в исходной тестовой ссылке и его не ожидали на выходе.
Автоматизируйте сравнение параметров
Короткий скрипт на Python выводит каждый переход и отмечает потерю. Он использует стандартный обработчик urllib.request.HTTPRedirectHandler и отслеживает только те рекламные параметры, которые присутствовали на входе в конкретный редирект.
from urllib.parse import parse_qs, urljoin, urlsplit
from urllib.request import HTTPRedirectHandler, Request, build_opener
TRACKED = {
"utm_id", "utm_source", "utm_medium", "utm_campaign",
"utm_term", "utm_content", "gclid", "gbraid", "wbraid", "yclid",
}
def params(url):
query = parse_qs(urlsplit(url).query, keep_blank_values=True)
return {name: tuple(query[name]) for name in query if name.lower() in TRACKED}
class AuditRedirects(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
destination = urljoin(req.full_url, newurl)
before, after = params(req.full_url), params(destination)
lost = sorted(name for name in before if name not in after)
changed = sorted(name for name in before if name in after and before[name] != after[name])
result = "OK"
if lost:
result = "LOST: " + ", ".join(lost)
if changed:
result += " | CHANGED: " + ", ".join(changed)
print(code, req.full_url, "->", destination, result, sep="\t")
return super().redirect_request(req, fp, code, msg, headers, destination)
url = "https://shop.example/start?utm_source=partner_digest&utm_medium=email&utm_campaign=october_test"
request = Request(url, headers={"User-Agent": "WiseLab-Redirect-Audit/1.0"})
with build_opener(AuditRedirects()).open(request, timeout=15) as response:
print(response.status, response.geturl(), "FINAL", sep="\t")Замените учебный адрес своей тестовой ссылкой. Скрипт выполняет обычный GET-запрос и следует максимумам библиотеки Python; для рабочего запуска добавьте ограничение числа переходов, обработку тайм-аута и сохранение CSV. Если сайт зависит от JavaScript, авторизации или мобильного приложения, повторите тест в инструментах разработчика браузера: вкладка Network показывает фактические запросы пользователя.
Как поставить задачу разработчику
Приложите исходную ссылку с безопасными тестовыми значениями, время проверки, цепочку статусов и первый проблемный Location. Формулировка может быть такой:
Запрос/tracker?...utm_campaign=october_testвозвращает 302 сLocation: /landing. В следующем URL отсутствуютutm_source,utm_mediumиutm_campaign. Нужно сохранить разрешённые параметры при этом переходе и повторить проверку цепочки до ответа 200.
Не просите безусловно переносить все параметры. Сайт может намеренно удалять служебные или опасные значения. Команда должна задать список разрешённых маркетинговых параметров, корректно кодировать значения и исключить персональные данные. Для gclid и yclid отдельно проверьте требования интеграций рекламных систем.
После исправления повторите тот же тест. Приёмка считается завершённой, когда ожидаемые параметры доходят до страницы со счётчиком, тестовый визит появляется в нужном отчёте, а заявка сохраняет согласованные поля источника в CRM.
Где продолжить проверку
Редирект — только один участок пути. Если метки дошли до конечного URL, но визит не находится в отчёте, проверьте загрузку счётчика, согласие на сбор данных, фильтры тестового трафика и выбранный период. Генератор UTM WiseLab помогает проверить структуру ссылок и словарь проекта; его массовая проверка не выполняет переходы, поэтому цепочку из этой статьи запускают отдельно.
Правила именования, ручную и автоматическую разметку соберите по гайду «UTM-метки: как сохранить смысл источника в аналитике». Для поиска визитов в Метрике используйте ответ «Как посмотреть UTM-метки в Яндекс Метрике». Если переходы уже накоплены под разными вариантами значений, продолжите с протоколом нормализации UTM без изменения исходного слоя.
Результат этой проверки — зафиксированная цепочка URL и первый переход, который потерял или изменил рекламный параметр. Этого достаточно, чтобы исправить конкретное правило редиректа и принять изменение на той же тестовой ссылке.
Источники
Материал подготовлен редакцией WiseLab с помощью AI. Источники и фактические утверждения проверены при подготовке.
Что думаете?
Загружаем комментарии…