Подключение Яндекс.Метрики к Next.js 16 (App Router) + TypeScript
В этом руководстве разберём, как правильно подключить Яндекс.Метрику к приложению на Next.js 16 с использованием App Router и TypeScript. Настроим инициализацию счётчика, корректное отслеживание переходов (включая UTM-метки) и избежим ошибок сборки.
Зачем нужна Яндекс.Метрика?
Яндекс.Метрика — это система веб-аналитики, которая помогает:
- отслеживать посещаемость и источники трафика;
- анализировать поведение пользователей (клики, переходы, глубину просмотров);
- измерять эффективность рекламных кампаний;
- собирать данные для улучшения конверсии.
Шаг 1. Устанавливаем библиотеку
bun add react-yandex-metrika
Шаг 2. Создаём компонент для Метрики
Создадим файл components/yandex-metrika.tsx. При реализации важно учесть два момента.
Потеря GET-параметров (UTM-меток и т.д.):
Хук usePathname возвращает только путь (например, /services), но отбрасывает параметры строки запроса (например, ?utm_source=yandex). Из-за этого теряется аналитика по источникам трафика и рекламным кампаниям. Решение — добавить useSearchParams() и передавать в Метрику полный URL.
Ошибка сборки при использовании useSearchParams:
Если добавить useSearchParams напрямую в компонент, импортируемый глобально в layout.tsx, Next.js выдаст ошибку при build — useSearchParams() should be wrapped in a suspense boundary. Параметры строки запроса неизвестны на этапе статической генерации страниц, поэтому официальная рекомендация Vercel/Next.js — вынести логику трекинга в отдельный микрокомпонент и обернуть его в <Suspense>.
// components/yandex-metrika.tsx
"use client";
import { usePathname, useSearchParams } from "next/navigation";
import { useEffect, Suspense } from "react";
import ym, { YMInitializer } from "react-yandex-metrika";
const YM_COUNTER_ID = 12345678; // замените на ваш ID счётчика
function RouterTracker() {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (pathname) {
const url = `${pathname}${searchParams.toString() ? `?${searchParams.toString()}` : ""}`;
ym("hit", url);
}
}, [pathname, searchParams]);
return null;
}
export const YandexMetrika = () => {
return (
<>
<YMInitializer
accounts={[YM_COUNTER_ID]}
options={{
defer: true,
webvisor: true,
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
}}
version="2"
/>
<Suspense fallback={null}>
<RouterTracker />
</Suspense>
</>
);
};
Что делает компонент?
- YMInitializer загружает скрипт Метрики и инициализирует счётчик.
- RouterTracker — отдельный микрокомпонент, отслеживающий изменения маршрута и GET-параметров через
usePathnameиuseSearchParams. - При каждом изменении маршрута отправляется событие
hitс полным URL, включая параметры строки запроса. - Обёртка
<Suspense fallback={null}>вокруг<RouterTracker />сохраняет статическую сборку (SSG) без ошибок.
Шаг 3. Подключаем в RootLayout
Чтобы Метрика работала на всех страницах, добавляем компонент в app/layout.tsx:
// app/layout.tsx
import type { ReactNode } from "react";
import {YandexMetrika} from "@/components/YandexMetrika";
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="ru">
<body>
{children}
<YandexMetrika />
</body>
</html>
);
}
Скрипт Метрики должен выполняться в браузере, поэтому компонент размещаем внутри <body>.
Шаг 4. Проверяем работу
Запускаем проект:
bun run dev
Затем проверяем сборку — ошибок, связанных с useSearchParams, быть не должно:
bun run build
После запуска открываем сайт в браузере и переходим по разным страницам. Чтобы проверить корректную передачу UTM-меток, откройте любую страницу с параметрами, например /page?utm_source=yandex, и убедитесь в инструментах разработчика (F12 → Network), что в запросах к mc.yandex.ru присутствует полный URL с параметрами. Визиты также должны появляться в разделе «Реальное время» в интерфейсе Яндекс.Метрики.
Дополнительные настройки (опционально)
Метрика позволяет отслеживать не только посещения, но и цели и пользовательские параметры:
// Отправка события-цели
ym("reachGoal", "goal_name");
// Передача пользовательских параметров
ym("userParams", { userId: 123 });
Итог
Теперь счётчик Яндекс.Метрики подключён к Next.js 16 (App Router) с TypeScript и работает корректно:
✅ инициализация при загрузке сайта;
✅ отслеживание переходов между страницами;
✅ передача полного URL, включая UTM-метки и GET-параметры;
✅ корректная статическая сборка (SSG) без ошибок useSearchParams.