in

How We Integrated Google AdSense into a Next.js App Router Project (the Right Way)

3 MINUTE READ

Google AdSense logo next to Next.js logo, representing integration between the two platforms

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 }) => (
  <Script 
    async 
    src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-${pId}`} 
    crossOrigin="anonymous" 
    strategy="afterInteractive" 
    />
);

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' ? (
        <> <GoogleAdsense pId="1234567890123456" />
            {/* Other third-party services */}
        </>) : null;
};

Then we included it at the bottom of our main layout:

src/app/layout.tsx
<body> {/* app content */} <RootLayoutServices /></body>

✅ This ensures your scripts only run live, never during local development.

Add public/ads.txt

Create this file and include:

public/ads.txt
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.

Blog content image showing AdSense panel

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 (<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-1234567890123456" data-ad-slot={slot} data-ad-format="auto" data-full-width-responsive="true" />);
};
export default AdSlot;

You can now place <AdSlot slot="1234567890" /> 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.

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.

Blog content image showing AdSense console warning

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!


VibeBerry Team

VibeBerry Team

About

The VibeBerry blog offers creative tools, tips, and tutorials - from fonts and symbols to colors, images, and design tricks. Whether you're styling content or learning something new, our guides help you create with clarity, flair, and ease.

Read More
Categories