skies.dev

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

3 min read

Add your Google Adsense client ID as an environment variable:

.env.local
NEXT_PUBLIC_GOOGLE_ADSENSE=ca-pub-5674178816323888

Then load the Adsense script once in your custom Document:

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

When Google gives you an ad unit snippet, wrap it in a React component instead of pasting the raw script everywhere.

Creating a Google Adsense Ad React Component

The patterns below work in any React app, not just Next.js.

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"
    />
  );
}

That gives you one place to manage the ad markup and the adsbygoogle.push({}) call.

Supporting Multiple Ad Unit Types

If you use more than one ad unit, map the variants to their props instead of hard-coding every slot inline:

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

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',
  },
};
components/GoogleAd.tsx
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]}
    />
  );
}

Preventing Overflow

Ads can overflow when the viewport gets smaller than the creative they load. Wrapping the ad in a container with overflow: hidden protects the rest of the layout:

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>

That can clip part of the ad, but it is usually better than letting the ad break your page.

Preventing Layout Shift

Ads often load after the surrounding content, which can cause Cumulative Layout Shift. Reserve space up front so the layout does not jump:

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>

Hiding Ads from Assistive Technology

Ads do not usually need to be exposed to screen readers or other assistive tools. If you decide to hide them, do it at the wrapper level:

<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>

That keeps the ad out of the accessibility tree and limits the damage from whatever markup the advertiser injects.

Hey, you! 🫵

Did you know I created a YouTube channel? I'll be putting out a lot of new content on web development and software engineering so make sure to subscribe.

(clap if you liked the article)

You might also like