Как обновлять Google AdSense при смене вкладок в Next.js App Router

    При разработке сайта на Next.js с использованием App Router и сложной вложенной маршрутизацией (например, Silo-архитектура) часто возникает проблема: рекламные блоки Google AdSense, размещённые в layout.tsx, не обновляются при переключении вкладок. Это происходит потому, что Next.js перехватывает клик по ссылке, обновляет URL через History API и подменяет только children, не перерендеривая родительский layout. В результате скрипт AdSense не получает сигнала о переходе на новую страницу, и реклама остаётся прежней, что снижает RPM и доход.

    Почему AdSense не обновляется в Next.js layout

    Google AdSense инициализирует рекламные блоки при загрузке страницы. В классическом многостраничном приложении (MPA) каждый переход - это полная перезагрузка, поэтому скрипт запускается заново. В Next.js с App Router используется клиентская навигация: layout остаётся смонтированным, а children меняются без перезагрузки. AdSense не отслеживает изменения History API, поэтому блоки не перерисовываются.

    Решение: принудительное обновление рекламы через useEffect

    Чтобы заставить AdSense перезагрузить объявления при смене вкладки, нужно отслеживать изменение пути (pathname) с помощью хука usePathname() из next/navigation. Внутри useEffect с зависимостью от pathname вызывается (window.adsbygoogle = window.adsbygoogle || []).push({}). Это сообщает скрипту, что нужно заново отобразить рекламные блоки на новой странице.

    Пример кода для layout.tsx

    import { useEffect } from 'react';
    import { usePathname } from 'next/navigation';
    
    export default function TypeLayout({ children }: { children: React.ReactNode }) {
      const pathname = usePathname();
    
      useEffect(() => {
        try {
          (window.adsbygoogle = window.adsbygoogle || []).push({});
        } catch (error) {
          console.error('AdSense push error:', error);
        }
      }, [pathname]);
    
      return (
        <div>
          <!-- Рекламный блок -->
          <ins className="adsbygoogle"
            style={{ display: 'block' }}
            data-ad-client="ca-pub-xxxxxxxxxxxxxxxx"
            data-ad-slot="1234567890"
            data-ad-format="auto"></ins>
          <script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
          {children}
        </div>
      );
    }

    Дополнительные рекомендации для стабильной работы

    • Используйте уникальные ID для рекламных блоков - если в layout несколько объявлений, присвойте каждому свой data-ad-slot.
    • Избегайте двойного push - проверьте, что скрипт внутри компонента не вызывает push() повторно, иначе AdSense может задублировать объявления.
    • Тестируйте в режиме разработки - используйте консоль браузера для отслеживания ошибок AdSense.
    • Для SSR/SSG - убедитесь, что код выполняется только на клиенте, обернув его в 'use client' или проверку typeof window !== 'undefined'.

    Альтернативные подходы

    Если useEffect не решает проблему полностью, рассмотрите другие методы:

    • Перезагрузка страницы - принудительный window.location.reload() при переключении вкладок, но это ухудшает UX и скорость.
    • Использование сторонних библиотек - например, react-ad-manager для более тонкого контроля над рекламой.
    • Размещение рекламы в page.tsx - перенесите блоки в дочерние страницы, чтобы они перерендеривались вместе с контентом.

    Заключение

    Проблема с обновлением Google AdSense при переключении вкладок в Next.js App Router решается простым добавлением useEffect с зависимостью от usePathname(). Это гарантирует, что скрипт AdSense получает сигнал о новой странице, и объявления перезагружаются корректно. Следуя приведённым рекомендациям, вы сохраните высокий RPM и обеспечите стабильную работу рекламных блоков.

    Часто задаваемые вопросы