Google AdSense is one of the easiest ways to monetize a website. But if you’re using Next.js with the App Router, setting it up properly requires a few key steps.
Here’s how we added AdSense to vibeberry.io - with full control, clean architecture, and production-ready integration.
1. Create an AdSense Account
Start by signing up at adsense.google.com/start.
You’ll need to:
- enter your domain (must be live and working)
- fill out basic business or personal info
- wait for Google to review your site
Once you’re in, AdSense will ask you to verify your site by adding a script and an ads.txt
file.
2. Add the Script and ads.txt
Create the Script Component
We created a reusable AdSense script loader and placed it here:
src/components/third-parties/GoogleAdsense.tsx
import { FC } from 'react';
import Script from 'next/script';
const GoogleAdsense: FC<{ pId: string }> = ({ pId }) => (
);
export default GoogleAdsense;
Load It in Production via a Centralized Service Component
To manage all third-party scripts cleanly, we created a wrapper component:
src/components/third-parties/RootLayoutServices.tsx
It loads services like AdSense, Analytics, Speed Insights, etc. - but only in production:
const RootLayoutServices: FC = () => {
return process.env.NODE_ENV === 'production' ? (
<>
{/* Other third-party services */}
>
) : null;
};
Then we included it at the bottom of our main layout:
// src/app/layout.tsx
{/* app content */}
✅ This ensures your scripts only run live, never during local development.
Add public/ads.txt
Create this file:
public/ads.txt
And include:
google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0
Replace pub-1234567890123456 with your Publisher ID, found under Account → Account information in AdSense.
This tells Google you’re allowed to show ads on your domain.
3. Create a Manual Ad Unit
After your site is approved:
- Go to Ads → By ad unit
- Choose Display Ads
- Set the format (we use responsive)
- Copy the generated data-ad-slot value
We prefer manual units over Auto Ads for better layout control.
4. Create a Custom Ad Slot Component
We placed our ad slot component here:
src/components/third-parties/AdSlot.tsx
'use client';
import { useEffect } from 'react';
const AdSlot = ({ slot }: { slot: string }) => {
useEffect(() => {
try {
(window.adsbygoogle = window.adsbygoogle || []).push({});
} catch (e) {
console.error(e);
}
}, []);
return (
);
};
export default AdSlot;
You can now place
wherever needed in your UI.
5. Handle App Router Navigation
Since we’re using Next.js App Router, AdSense and Analytics won’t automatically detect route changes. We fixed this with:
src/components/third-parties/AnalyticsRouter.tsx
'use client';
import { useEffect, useRef } from 'react';
import { usePathname } from 'next/navigation';
export default function AnalyticsRouter() {
const path = usePathname();
const first = useRef(true);
useEffect(() => {
if (first.current) {
first.current = false;
return;
}
window.gtag?.('event', 'page_view', {
page_path: path,
page_location: window.location.href,
});
}, [path]);
return null;
}
This ensures AdSense/GA4 continue to track page views correctly as users navigate between routes.
6. Respect Consent Requirements (EU, US)
If you serve users in the EU, California, or other regions with privacy laws, you must obtain user consent before showing personalized ads.
You can:
- Use a Consent Management Platform (CMP)
- Or implement manual logic using
gtag('consent', ...)
Without consent, Google may block personalized ads or fall back to lower-paying non-personalized ones.
7. Console Warning (You Can Ignore It)
During development or even in production, you may see this browser console warning:
It’s harmless and caused by how Next.js handles scripts. Your ads will still load and work perfectly - you can safely ignore it.
Recap
Here’s what we did on vibeberry.io:
- ✅ Registered an AdSense account
- ✅ Verified the site with a script and ads.txt
- ✅ Created manual display ad units
- ✅ Centralized all scripts in RootLayoutServices
- ✅ Displayed ads only in production
- ✅ Handled route changes with App Router
- ✅ Respected consent rules for personalized ads
Final Thoughts
Setting up AdSense on a modern Next.js project can feel confusing at first - especially with the App Router and all the privacy requirements. But once you break it down into steps, it’s totally manageable.
If you have any questions or run into something tricky - drop a comment below. Thanks for reading - and good luck with your integration!