How to Add Google Adsense Ads to a Next.js App

4 min read

Add your Google Adsense client ID as an environment variable.

.env.local
NEXT_PUBLIC_GOOGLE_ADSENSE=ca-pub-5674178816323888

Then, add the following <script> in the <Head> of _document.tsx. This way, Google Adsense loads once your Next app mounts.

<script
  async
  src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${process.env.NEXT_PUBLIC_GOOGLE_ADSENSE}`}
  crossOrigin="anonymous"
/>

In the Adsense console, create a new ad unit. You’ll be asked to copy some code that looks like this. Don’t copy it yet. Here’s where React will come in.

<script
  async
  src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5674178816323888"
  crossorigin="anonymous"
></script>
<!-- responsive -->
<ins
  class="adsbygoogle"
  style="display:block"
  data-ad-client="ca-pub-5674178816323888"
  data-ad-slot="7181773959"
  data-ad-format="auto"
  data-full-width-responsive="true"
></ins>
<script>
  (adsbygoogle = window.adsbygoogle || []).push({});
</script>

Creating a Google Adsense Ad React Component

The information in the rest of this article applies to any React app whether you’re using Next.js, Gatsby.js, Create React App, or a custom React setup.

Inspired by this GitHub comment, create a component to encapsulate your Google ad.

components/GoogleAd.tsx
import {useEffect} from 'react';

export function GoogleAd() {
  useEffect(() => {
    try {
      // @ts-ignore
      (window.adsbygoogle = window.adsbygoogle || []).push({});
    } catch (err) {
      console.error(err);
    }
  }, []);

  return (
    <ins
      className="adsbygoogle"
      style={{display: 'block'}}
      data-ad-client={process.env.NEXT_PUBLIC_GOOGLE_ADSENSE}
      data-ad-slot="7181773959"
      data-ad-format="auto"
      data-full-width-responsive="true"
    />
  );
}

Now you can place your Google ad where you want.

Supporting Multiple Ad Unit Types

Define an enum for each ad unit you define. For example,

components/GoogleAd.tsx
export enum AdType {
  DEFAULT,
  ARTICLE,
  VERTICAL,
}

Then, set up a Record that maps each ad unit to its corresponding props.

components/GoogleAd.tsx
const adUnitProps: Record<AdType, any> = {
  [AdType.DEFAULT]: {
    'data-ad-slot': '7181773959',
    'data-ad-format': 'auto',
    'data-full-width-responsive': 'true',
  },
  [AdType.ARTICLE]: {
    'data-ad-slot': '3197857275',
    'data-ad-format': 'fluid',
    'data-ad-layout': 'in-article',
  },
  [AdType.VERTICAL]: {
    'data-ad-slot': '8863578035',
    'data-ad-format': 'auto',
    'data-full-width-responsive': 'true',
  },
};

Modify your GoogleAd component to accept a type prop.

components/GoogleAd.tsx
import {useEffect} from 'react';

interface GoogleAdProps {
variant?: AdType;
}
export function GoogleAd({variant = AdType.DEFAULT}: GoogleAdProps) {
useEffect(() => { try { // @ts-ignore (window.adsbygoogle = window.adsbygoogle || []).push({}); } catch (err) { console.error(err); } }, []); return ( <ins className="adsbygoogle" style={{display: 'block'}} data-ad-client={process.env.NEXT_PUBLIC_GOOGLE_ADSENSE}
{...adUnitProps[variant]}
/> ); }

Now you should be able to use Google Adsense ads on your Next.js site.

Fixing Overflow with Adsense Ads

Sometimes the ads can overflow when resizing the viewport.

Here’s what it could look like.

Main Content
Ad

Following Google’s advice on overflow issues, we’ll hide the overflow content.

components/GoogleAd.tsx
<div style={{overflow: 'hidden'}}>
  <ins
    className="adsbygoogle"
    style={{display: 'block'}}
    data-ad-client={process.env.NEXT_PUBLIC_GOOGLE_ADSENSE}
    {...adUnitProps[variant]}
  />
</div>

Setting overflow: 'hidden' might cut off part of your ad when the viewport’s resized. But at least the ad won’t break your site’s layout if the viewport shrinks.

Here’s what it looks like when you set overflow: 'hidden'.

Main Content
Ad

Preventing Cumulative Layout Shift with Google Adsense

Cumulative Layout Shift (CLP) occurs when the ad loads, pushing the other content on your page out of the way. CLP will hurt your Lighthouse score and SEO.

To minimize layout shift, preemptively set a height and width to make room for your ad.

components/GoogleAd.tsx
<div style={{overflow: 'hidden', minWidth: '300px', minHeight: '250px'}}>
  <ins
    className="adsbygoogle"
    style={{display: 'block'}}
    data-ad-client={process.env.NEXT_PUBLIC_GOOGLE_ADSENSE}
    {...adUnitProps[variant]}
  />
</div>

Remove Ads from Assistive Technologies like Screen Readers

The problem with Google Adsense ads is you inject an <iframe> containing the advertisers content and markup on your site. Then, when you run a Lighthouse check on your site, the advertiser’s problems become your problem. If the ad contains bad HTML decisions, you will get dinged for it.

Let’s address this by hiding the aria contained by the ad. It doesn’t make sense to expose an ad to assistive technologies like screen readers anyway. But you should do your own testing and see if it makes sense to follow this advice for your own business.

If you make this change, then your Lighthouse score won’t be affected by any crap the advertiser puts in their markup.

<div
  aria-hidden={true}
  style={{overflow: 'hidden', minWidth: '300px', minHeight: '250px'}}
>
  <ins
    className="adsbygoogle"
    style={{display: 'block'}}
    data-ad-client={process.env.NEXT_PUBLIC_GOOGLE_ADSENSE}
    {...adUnitProps[variant]}
  />
</div>

If you have any more “Google Adsense with React” tips that you think would be useful to add, let me know on Twitter @swkeever.

Hope this info helps you prosper. 💸