How to Add Google Ad Sense in Next.js 13 With App Router, Auto Ads and Unit Ads

Hello everyone! Today, I'm going to talk about how to run Google AdSense and Google AdSense ad units.

The Problem

We can add the AdSense code in the head tag of a Next.js 13 app router, but the problem arises when dealing with Google AdSense ad units. When using the new method, we have to assign our ad component as a client, but the AdSense ad unit code does not refresh on page changes.

Solution 1: Auto Ads (Follow this for ad units as well)

Firstly, go to the RootLayout component, which looks like the following:

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head></head>
      <body className="bg-gray-100 font-sans">{children}</body>
    </html>
  );
}

The Google AdSense code you need to convert is as follows:

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1234567890123456" crossorigin />

Now, convert the code to a Next.js Script component:

<Script
  async
  src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1234567890123456"
  crossOrigin="anonymous"
  strategy="lazyOnload"
/>

Simply add this code to the head tag, and remember that the strategy should be set to lazyOnload, which increases the chances of the code running fine. Also, set crossOrigin to "anonymous".

Solution 2: Google AdSense Ad Unit Codes in App Router

Now, you have the code from the Google AdSense ad unit, which looks like this:

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1234567890123456" crossorigin="anonymous"></script>
<!-- Homepage Leaderboard -->
<ins class="adsbygoogle" style="display:inline-block;width:728px;height:90px" data-ad-client="ca-pub-1234567890123456" data-ad-slot="1234567890"></ins>
<script>
(window.adsbygoogle = window.adsbygoogle || []).push({});
</script>

The first part of the code (the first script tag) is already rendered in the head tag, as we added it in the auto ads solution. So, we will focus on the remaining code.

After converting it to the Next.js version, it looks like this:

<ins
  className="adsbygoogle"
  style={{ display: "inline-block", width: 728, height: 90 }}
  data-ad-client="ca-pub-1234567890123456"
  data-ad-slot={1234567890}
/>
<script dangerouslySetInnerHTML={{ __html: "(window.adsbygoogle = window.adsbygoogle || []).push({});" }} />

You can now add this code. However, there is an issue: the page needs to be refreshed for the ad to load, and it doesn't load again on other pages due to the smooth navigation of Next.js.

To resolve this, we need to update our code, which might seem complex but it works completely.

First, create a new AdCode.jsx file. Note: It should be in JSX format, not .ts.

First, add the following code in a class component (do not use a function component with useEffect() as it only works partially):

class AdCodeWithoutRouter extends React.Component {
  renderAds() {
    (window.adsbygoogle = window.adsbygoogle || []).push({});
  }

  componentDidMount() {
    this.renderAds();
  }

  componentDidUpdate(prevProps) {
    if (this.props.router.asPath !== prevProps.router.asPath) {
      this.renderAds();
    }
  }

  render() {
    return (
      <div className="container mx-auto text-center" aria-hidden={true}>
        <ins
          className="adsbygoogle"
          style={{ display: 'block', width: '100%' }}
          data-ad-client="ca-pub-1234567890"
          data-ad-slot="123456"
          data-ad-format="auto"
          data-full-width-responsive="true"
        ></ins>
      </div>
    );
  }
}

Next, you need to import some modules and modify the function component. The complete file will look like this. Make sure to import useRouter from 'next/navigation' in Next.js 13:

'use client';
import React from 'react';
import { useRouter } from 'next/navigation';

class AdCodeWithoutRouter extends React.Component {
  renderAds() {
    (window.adsbygoogle = window.adsbygoogle || []).push({});
  }

  componentDidMount() {
    this.renderAds();
  }

  componentDidUpdate(prevProps) {
    if (this.props.router.asPath !== prevProps.router.asPath) {
      this.renderAds();
    }
  }

  render() {
    return (
      <div className="container mx-auto text-center" aria-hidden={true}>
        <ins
          className="adsbygoogle"
          style={{ display: 'block', width: '100%' }}
          data-ad-client="ca-pub-1234567890"
          data-ad-slot="123456"
          data-ad-format="auto"
          data-full-width-responsive="true"
        ></ins>
        <script dangerouslySetInnerHTML={{ __html: '(window.adsbygoogle = window.adsbygoogle || []).push({});' }}></script>
      </div>
    );
  }
}

const AdCode = () => {
  const router = useRouter();
  return <AdCodeWithoutRouter router={router} />;
};

export default AdCode;

In the modified code, the componentDidMount function runs when the component is first loaded, and componentDidUpdate is triggered when navigating to new pages. These functions ensure that the ads are rendered correctly.

Finally, you can use the AdCode component wherever you need it.

Bye.

Please note that the above code assumes you are using Next.js version 13. Make sure to import the correct modules and follow the appropriate syntax based on your Next.js version.

Did you find this article valuable?

Support Shrikant Dhayje by becoming a sponsor. Any amount is appreciated!