Как обновлять 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 и обеспечите стабильную работу рекламных блоков.