seomix.

Подключение Яндекс.Метрики к Next.js 16 (App Router) + TypeScript

Подключение Яндекс.Метрики к 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 выдаст ошибку при builduseSearchParams() 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.

Полезные ссылки