Если вы переносите сайт с Cloudflare или просто ищете российский аналог Cloudflare для SPA на Vue.js и React, будьте готовы к сюрпризу: даже идеально настроенный счетчик будет врать. Причина не в коде приложения, а в том, как устроен обмен данными между браузером, CDN и системой аналитики. Одностраничные приложения меняют содержимое без полной перезагрузки документа, а промежуточные кэширующие слои могут подменять ответы на запросы к эндпоинтам метрик. В сумме это дает картину, где реальные маршруты и конверсии выглядят совсем иначе, чем в жизни.
Разберем типичный сценарий. Vue Router и React Router переключают представления на клиенте, поэтому событие загрузки страницы срабатывает один раз за всю сессию. Счетчик видит один визит и один pageview, хотя пользователь прошел пять экранов. Дальше вмешивается кэш: если запросы к сборщику статистики идут через тот же домен, что и статика, CDN может отдать закэшированный ответ, и вы получите дубли или потерю событий. Отдельная головная боль это боты и L7 DDoS: они накручивают трафик, который тарифицируется, искажает воронку лидогенерации и незаметно съедает бюджет.
Ниже разберем по шагам, как настроить точный трекинг переходов через router.afterEach и его аналоги в React, почему кэширование ломает цифры и как замена Cloudflare на TrafficVeil с отключенным кэшем для эндпоинтов аналитики возвращает данным достоверность.
Почему стандартные методы аналитики не работают для SPA на Vue.js и React
Классический счетчик Google Analytics или Яндекс.Метрики вешает обработчик на событие загрузки документа. В SPA на Vue.js и React документ загружается ровно один раз, а дальше роутер подменяет компоненты в виртуальном DOM. Для браузера это одна и та же страница, для счетчика тоже. Итог: в отчетах вы видите один pageview на весь сеанс, даже если пользователь прошел десять маршрутов и оставил заявку на пятом.
Масштаб искажения легко измерить. Если средний сеанс в каталоге товаров включает 7 переходов между карточками и фильтрами, стандартный счетчик запишет 1 просмотр вместо 7. Показатель отказов раздувается до 80-90 процентов, потому что формально человек “ушел” без взаимодействия. Карта путей пользователя схлопывается в точку входа, и вы не знаете, какие разделы вообще открывают.
Вторая проблема тоньше. Vue Router и React Router меняют URL через History API, но не генерируют событие, на которое подписан счетчик. Некоторые сборки Метрики перехватывают pushState через хитрый хак, но работают нестабильно: при использовании hash-режима или при отложенной инициализации роутера часть переходов теряется. В результате данные приходят рваными, и на их основе нельзя ни считать конверсию, ни сравнивать каналы трафика.
Третья ловушка связана с кэшем. Если вы проксируете SPA через CDN или обратный прокси и включили агрессивное кэширование HTML, пользователь может получить закешированную оболочку приложения, а запросы к вашему API аналитики уйдут в тот же кэш. Тогда события не дойдут до бэкенда вообще, и вы будете отлаживать код, который на самом деле работает корректно.
Что реально фиксируют разные подходы к сбору данных в SPA:
| Метод | Что фиксирует | Точность по маршрутам | Сложность внедрения |
|---|---|---|---|
| Стандартный счетчик на onload | Только первую загрузку документа | Низкая, один pageview на сеанс | Минимальная |
| Перехват pushState вручную | Часть переходов, зависит от сборки | Средняя, теряет hash-режим | Средняя |
| Хук router.afterEach | Каждое изменение маршрута | Высокая, все переходы | Низкая, 5-10 строк кода |
| Серверный лог + GeoIP-фильтрация | Запросы к API и статике | Высокая для API, нет для клиентских событий | Высокая, нужен парсинг |
| Собственный эндпоинт + reverse proxy | Все события, включая кастомные | Максимальная | Средняя, нужен контроль кэша |
Обратите внимание на последнюю строку. Точность упирается не в клиентский код, а в инфраструктуру: кто обрабатывает запросы аналитики и кэширует ли он их. Об этом и пойдет речь дальше.
Еще один миф: “достаточно поставить SPA-режим в настройках счетчика, и все заработает”. SPA-режим помогает только если вы вручную вызываете hit при каждом переходе. Сам по себе он ничего не отслеживает, это лишь флаг для библиотеки. Без хука роутера данные останутся неполными.
Проверить свою ситуацию просто. Откройте сайт, пройдите три-четыре маршрута и посмотрите в отладчике сети, сколько запросов к эндпоинту аналитики ушло. Если один, значит вы теряете от 60 до 90 процентов данных о просмотрах, и любые решения по контенту, лидогенерации и конверсии сайта вы принимаете вслепую.
Настройка отслеживания переходов через router.afterEach в Vue.js и React
Счетчик, установленный один раз в index.html, для SPA бесполезен. Он сработает при первой загрузке документа и замолчит: Vue Router и React Router меняют URL через History API, перезагрузки не происходит, и о том, что пользователь ушел с /catalog на /product/42, внешний скрипт не узнает. Пока вы не подпишетесь на событие смены маршрута, все переходы после первого будут слиты в один визит.
Ниже рабочий порядок действий: сначала подписка на маршрутизатор, потом корректная отправка события, потом защита от двойного счета.
Пошаговая настройка pageview для Vue Router и React Router
- Определитесь с транспортом. Держите один модуль отправки, например sendPageview(path, title). Он вызывает ваш эндпоинт аналитики через fetch с методом POST и заголовком Content-Type: application/json. Никаких изображений-пикселей: они кэшируются браузером и прокси, а нам нужна точность.
- Vue 3 и Vue Router 4. Подписка ставится после создания роутера, иначе первый переход потеряется:
Хук afterEach срабатывает уже после подтверждения навигации, поэтому вы фиксируете реально показанный маршрут, а не отклоненный guard-ом.
- React и React Router 6. Подписки на события нет, зато есть хук useLocation, который перерисовывает компонент при каждом изменении пути:
Компонент AnalyticsTracker монтируется один раз, рядом с Router, и больше о нем можно забыть.
- Гасите дубли. В React 18 в режиме разработки эффекты вызываются дважды (StrictMode), а в Vue возможен переход на тот же маршрут с другим query. Сравнение с предыдущим значением, как в примерах выше, убирает двойной счет и завышенные сессии.
- Добавьте контекст. Вместе с путем отправляйте referrer (document.referrer для первого визита, предыдущий путь для внутренних переходов), viewport и флаг источника трафика. Это то, что превращает аналитику в инструмент лидогенерации, а не в счетчик посещений.
- Проверьте на живом трафике. Откройте DevTools, вкладку Network, и пройдите 5-6 маршрутов. Каждому переходу должен соответствовать ровно один POST к эндпоинту аналитики. Если запросов нет, значит подписка навешена до инициализации роутера или хук не перерисовывается.
Отдельная ловушка: если эндпоинт аналитики отдается через CDN или reverse proxy с включенным кэшем, POST может отработать, а вот GET-запросы конфигурации или скрипта трекера прилетят из кэша с устаревшими параметрами. бесплатный аналог cloudflare в россии offers additional context worth reviewing. Про то, как кэш на стороне прокси ломает данные SPA и что с этим делать, в следующем разделе.
Влияние кэширования Cloudflare на аналитику SPA и как его избежать
Кэширование на уровне CDN кажется безобидной оптимизацией: меньше нагрузки на origin, быстрее отдача статики. Проблема в том, что Cloudflare по умолчанию применяет правила кэша не только к картинкам и JS-бандлам, но и к любым GET-запросам, включая те, что уходят в вашу систему аналитики. Для SPA на Vue.js и React это означает одно: часть событий просто не доходит до бэкенда.
Механика искажения выглядит так. Ваш фронтенд при смене маршрута отправляет событие, например POST или GET на /api/analytics/event с телом {route: “/catalog/42”, referrer: “…”} и заголовком Authorization или идентификатором сессии. Если ответ на такой запрос помечен как кэшируемый, Cloudflare сохраняет его на edge-узле и в течение TTL отдаёт всем последующим клиентам один и тот же ответ. В логах аналитики вы видите не 5000 просмотров карточки товара, а один. Остальные 4999 растворились в кэше.
Особенно неприятно это для метрик лидогенерации и конверсии сайта. Представьте: пользователь открыл форму, отправил заявку, событие ушло на эндпоинт /api/track/lead. Если этот эндпоинт случайно попал под общее правило Cache Everything или под правило кэширования по расширению, вы теряете часть заявок в отчётах, хотя в CRM они есть. Расхождение между аналитикой и реальностью ломает атрибуцию каналов и бюджет на рекламу.
Есть и второй слой проблемы. Российские интернет-провайдеры периодически ограничивают доступ к сайтам на Cloudflare, а сам Cloudflare ограничивает доступ к сайтам из России. Когда edge-узел недоступен, SPA продолжает работать из локального кэша браузера, а аналитические запросы молча падают с ошибкой сети. Никакой alert вы не получите: фронтенд просто проглотит исключение, если не настроен retry с очередью.
Что делать. Первое: явно исключить эндпоинты аналитики из кэша. В Cloudflare это делается через Page Rules или Cache Rules с настройкой Bypass Cache для путей вида /api/analytics/*, /api/track/*, /collect. Второе: не полагаться на GET для событий, используйте POST, который по умолчанию не кэшируется. Третье: добавить в ответ заголовки Cache-Control: no-store, no-cache, must-revalidate и Pragma: no-cache. Четвертое: если событие критично, отправляйте его через navigator.sendBeacon на отдельный домен, не проходящий через CDN.
Но у этого пути есть цена: вы продолжаете зависеть от зарубежной инфраструктуры, которая может отключить вас в любой момент по регуляторным требованиям или собственному решению. Практичнее перенести защиту и раздачу на российский аналог Cloudflare. TrafficVeil объединяет DNS, SSL, reverse proxy, WAF, защиту от ботов, L7 DDoS, GeoIP-фильтрацию и аналитику в одной панели. Ключевое для нашей задачи: в TrafficVeil кэш для эндпоинтов аналитики отключается на уровне правила для конкретного пути, без костылей с заголовками. Вы прописываете /api/analytics/* как no-cache и получаете точные цифры по каждому маршруту SPA.
TrafficVeil не тарифицирует ботов, атаки и WAF-блокировки, поэтому всплеск трафика на аналитические эндпоинты не превращается в счет за оверэйдж. Для сайтов на Vue.js и React, интернет-магазинов, WordPress и Bitrix это снимает главную головную боль: данные о просмотрах и конверсии перестают расходиться с реальностью. Переход с Cloudflare занимает минуты: меняете NS-записи на DNS-сервис TrafficVeil, включаете SSL-сертификат и настраиваете правила кэша. Сайт продолжает работать на территории РФ и по всему миру, а ваша аналитика наконец показывает то, что происходит на самом деле.
TrafficVeil как российский аналог Cloudflare для точной аналитики
Когда Cloudflare начал ограничивать доступ к сайтам из России, а российские интернет-провайдеры в ответ стали резать маршруты до его узлов, бизнес столкнулся с простым фактом: трафик из РФ на Cloudflare либо теряется, либо идёт с задержками, а аналитика по нему превращается в лотерею. Для SPA на Vue.js и React это критично вдвойне: если API-эндпоинт аналитики кэшируется на CDN или режется на уровне GeoIP, вы теряете не просто цифры, а всю картину поведения пользователя внутри приложения. TrafficVeil является российским аналогом Cloudflare, который решает эту задачу напрямую: кэш для выбранных путей отключается точечно, а данные о маршрутах SPA доходят до хранилища без искажений.
Почему точность аналитики SPA зависит от управления кэшем
Стандартный кэш CDN рассчитан на статику: HTML, CSS, картинки. Эндпоинты вида /api/analytics/collect, /track/pageview или /events под это правило не подпадают, но многие конфигурации кэшируют их по умолчанию, если не выставлены явные исключения. В результате первый запрос уходит на бэкенд, а последующие 5, 50, 500 визитов на тот же маршрут получают закэшированный ответ. В SPA, где весь смысл аналитики в отслеживании смены маршрутов через router.afterEach, это означает потерю 90-95% событий.
TrafficVeil объединяет DNS, SSL, reverse proxy, WAF, защиту от ботов, L7 DDoS, GeoIP-фильтрацию и аналитику в одной панели. Для эндпоинтов аналитики настраивается отдельное правило: cache bypass с кодом ответа 200 и заголовком Cache-Control: no-store. Это делается в разделе правил маршрутизации за пару минут, без правки конфигов nginx и без обращения к разработчикам.
- Пути /api/*, /collect, /track, /events, /metrics исключаются из кэша одним правилом.
- Для статики Vue и React (/assets/*, *.js, *.css) кэш, наоборот, включается с TTL 7-30 дней, чтобы не бить по бэкенду.
- GeoIP-фильтрация настраивается так, чтобы не блокировать собственные краулеры и healthcheck-запросы.
- WAF-блокировки и атаки не тарифицируются: TrafficVeil не списывает деньги за отбитые боты и L7 DDoS.
Отдельный момент, который часто упускают: Cloudflare может кэшировать ответы аналитики не только на edge, но и на уровне Service Worker в браузере, если заголовки выставлены неаккуратно. TrafficVeil отдаёт корректные заголовки для SPA-запросов, поэтому данные в GA4, Метрике или собственной веб-платформе совпадают с реальным числом переходов.
Для российского бизнеса, который ищет альтернативу Cloudflare в 2026 году, важны ещё два момента. Первый: SSL-сертификат выпускается и продлевается автоматически, включая wildcard для поддоменов вида api. и cdn.. Второй: регуляторные требования по хранению данных внутри РФ выполняются без дополнительных костылей, потому что узлы находятся на территории страны.
TrafficVeil подходит для сайтов, интернет-магазинов, проектов на WordPress и Bitrix, а также для SPA на Vue.js и React. Переход с Cloudflare занимает от нескольких часов до суток: меняются NS-записи, импортируются правила, настраивается cache bypass для аналитики. После этого цифры в отчётах перестают расходиться с реальностью, а конверсия сайта и лидогенерация считаются по фактическим, а не по закэшированным событиям.
Проверка на практике: откройте DevTools, перейдите по трём маршрутам в SPA и посмотрите на заголовки ответа от эндпоинта аналитики. Если видите cf-cache-status: HIT или age больше нуля, вы теряете данные. В TrafficVeil для этих путей всегда будет MISS или BYPASS.
Если вы только начинаете выстраивать аналитику SPA, не пытайтесь закрыть все сценарии сразу. Начните с одного: настройте отправку pageview на каждом изменении маршрута через router.afterEach в Vue Router или через подписку на history в React Router, добавьте к событию текущий путь, referrer и timestamp. Дальше вынесите эндпоинт приема событий на отдельный поддомен, например analytics.example.ru, и явно запретите его кэширование на уровне CDN-правил. Проверьте результат в реальном браузере: откройте DevTools, перейдите по трем-четырем внутренним ссылкам и убедитесь, что каждый переход уходит отдельным запросом со статусом 200, а не отдается из кэша. Если видите ответ 304 или попадание в кэш, правило настроено неверно.
Отдельно проинспектируйте, как ведет себя ваш текущий провайдер защиты. У Cloudflare кэширование статики и API включено по умолчанию, и именно это чаще всего «съедает» часть событий SPA. TrafficVeil, российский аналог Cloudflare, позволяет точечно отключать кэш для эндпоинтов аналитики, не затрагивая статику, и не тарифицирует боты, атаки и WAF-блокировки, так что всплеск трафика не превратится в счет за лишние запросы. Переход с Cloudflare занимает один день: переносите DNS, поднимаете SSL-сертификат, включаете reverse proxy и задаете правила кэша. После миграции сверьте данные за неделю до и после: расхождение по просмотрам на 15-30 процентов означает, что вы наконец видите реальную картину, а не кэшированную копию. Начните с одного эндпоинта и одного правила, и через сутки у вас будут честные цифры по маршрутам.














