Блог · Для разработчиков
Аналитика для React, Vue и Next.js: как считать переходы в SPA
Поставили счётчик на сайт на React или Vue, а в отчёте почти все просмотры приходятся на главную, и у каждой сессии одна страница? Это не ошибка аналитики, а особенность одностраничных приложений. Разберём, почему так происходит и как MetricsOn считает такие сайты правильно.
Почему счётчик видит только первую страницу
На обычном сайте каждый переход — это загрузка новой страницы: браузер запрашивает HTML, счётчик запускается заново и отправляет просмотр. В одностраничном приложении (SPA) страница загружается один раз, а дальше роутер меняет содержимое и адрес в строке браузера через History API — без перезагрузки. Счётчик, который отправляет просмотр только при загрузке, переходов просто не замечает.
Отсюда типичные симптомы:
- почти все просмотры — на странице входа на сайт;
- отказов под 100%: каждая сессия «смотрела одну страницу»;
- не работают цели по адресу страницы, если до неё доходят переходами внутри приложения.
Как это решает MetricsOn
Скрипт MetricsOn следит за сменой адреса сам — дополнительный код или плагины для роутера не нужны:
- Переходы через History API. Вызовы
history.pushStateиhistory.replaceState, которыми пользуются React Router, Vue Router, Next.js и Nuxt, засчитываются как новый просмотр. Предыдущая страница записывается источником перехода — в отчётах виден путь по сайту. - Кнопки «Назад» и «Вперёд» браузера тоже считаются переходами.
- Хеш-роутинг. Адреса вида
/#/catalogи/#!/catalog— это отдельные страницы. А якоря вроде/about#team— нет: прокрутка к разделу не новый просмотр. - Время на странице считается с момента, когда страница показана, и отправляется при каждом переходе, а не только при закрытии вкладки.
- Защита от двойного подключения. Если скрипт попал на страницу дважды — например, из шаблона и из компонента, — второй экземпляр ничего не делает, и просмотры не удваиваются.
Одна тонкость: адрес сравнивается целиком, вместе с параметрами. Если приложение записывает фильтры каталога в адрес — /catalog?color=red, — каждая смена фильтра будет отдельным просмотром.
Как подключить
Код счётчика — одна строка, токен сайта берётся в кабинете MetricsOn:
<script src="https://metricson.ru/tracker.js" data-token="ВАШ_ТОКЕН" async></script>
Подключайте его один раз — в общем шаблоне, а не в компоненте страницы.
Vite, Create React App, Vue CLI. Вставьте строку в <head> файла index.html в корне проекта.
Next.js (App Router). В корневом app/layout.tsx:
import Script from 'next/script'
export default function RootLayout({ children }) {
return (
<html lang="ru">
<body>
{children}
<Script
src="https://metricson.ru/tracker.js"
data-token="ВАШ_ТОКЕН"
strategy="afterInteractive"
/>
</body>
</html>
)
}
В Pages Router то же самое кладут в pages/_app.tsx.
Nuxt 3. В nuxt.config.ts:
export default defineNuxtConfig({
app: {
head: {
script: [
{ src: 'https://metricson.ru/tracker.js', 'data-token': 'ВАШ_ТОКЕН', async: true }
]
}
}
})
События из кода приложения
Для целей по действиям — регистрации, оплате, отправке формы — вызывайте metricson.track. Скрипт загружается асинхронно, а у посетителей с включённым Do Not Track не запускается вовсе, поэтому вызывайте его через проверку — так код не упадёт, если счётчика нет:
async function onSubmit(data) {
await api.signup(data)
window.metricson?.track('signup')
}
В TypeScript добавьте объявление, чтобы компилятор знал о глобальном объекте:
declare global {
interface Window { metricson?: { track(name: string): void } }
}
Как проверить
На localhost и на адресах вида 192.168.0.10 счётчик специально молчит, чтобы разработка не попадала в статистику. Проверяйте на тестовом стенде с доменом или сразу на боевом сайте:
- Откройте сайт и походите по нескольким разделам.
- В отчёте «Реальное время» должна меняться страница, которую вы сейчас смотрите.
- Если включён Do Not Track — в Firefox и некоторых других браузерах это настройка «Не отслеживать», — визит не засчитается. Для проверки отключите её или откройте сайт в другом браузере.
Итог
Одностраничному приложению не нужна особая аналитика — нужен счётчик, который понимает, как устроены переходы без перезагрузки. MetricsOn подключается одной строкой в общий шаблон и дальше сам считает просмотры, путь по сайту и время на страницах.