How to Add Google Ad Sense in Next.js 13 With App Router, Auto Ads and Unit Ads
Tags: nextjs, adsense, nextjs13, shriekdj
Published: 2023-06-22 15:40:17

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:

```tsx
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:

```html
<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:

```jsx
<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:

```html
<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:

```jsx
<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):

```jsx
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:

```jsx
'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.