Add Google AdSense to your Next.js app.
This package is deeply inspired by nextjs-google-adsense.
Why I don't use nextjs-google-adsense directly? Because it only support Auto Ads and Responsive Display Ad. I want to use In-article Ads. So I decided to create a new package. (read 👾 Why next-google-adsense? for more details)
Give me a ⭐ if you like it.
- Support SSR (Server-Side Rendering), SSG (Static Site Generation) and CSR (Client-Side Rendering)
- Support TypeScript
- Zero Dependencies
- Dummy Ad Support for Development - Preview ads locally without real AdSense integration
- Theoretically support all AdSense AD types (see 🎨 Create a custom layout for more details)
- Create
ads.txtautomatically (see Initialization / Verification for more details)
- 👾 Why next-google-adsense?
- 📦 Requirements
- 🚀 Getting Started
- 📖 API Reference
- 🎨 Create a custom layout
- 🐛 Known Issues
- ⭐ TODO
- 🤝 Contributing
- 📝 License
- ☕ Donation
| next-google-adsense (this) | nextjs-google-adsense | |
|---|---|---|
| TypeScript | ✅ | ✅ |
| Support Auto Ads | ✅ | ✅ |
| Support Display Ad | ✅ | ✅ |
| Support In-feed Ad | ✅ | ❌ |
| Support In-article Ad | ✅ | ❌ |
| Support Matched Content Ad | ✅ | ❌ |
Dynamic ads.txt |
✅ | ❌ |
| Multiple ADs on one page | ✅ | |
| Dummy Ad for Development | ✅ | ❌ |
*1: According to the their documentation seems it is ok to use multiple ADs on one page. But I found that it will cause an error.
- Next.js 11.0.0 or higher.
- React 17.0.0 or higher.
npm install next-google-adsenseVisit the npm page.
There are two ways to verify your site (of course you can implement both):
-
AdSense code snippet
// pages/_app.tsx // import the module import { GoogleAdSense } from "next-google-adsense"; const App = ({ Component, pageProps }) => { return ( <> <GoogleAdSense publisherId="pub-XXXXXXXXXXXXXXXX" // 👈 16 digits isAutoAd={false} // 👈 true if you want to use Auto Ads /> {/* or */} <GoogleAdSense /> {/* if NEXT_PUBLIC_ADSENSE_PUBLISHER_ID is set */} <Component {...pageProps} /> </> ); }; export default App;
You can also add the
publisherIdas environment variable asNEXT_PUBLIC_ADSENSE_PUBLISHER_ID. The environment variable will override the prop if both are set.[!NOTE]\ No need to add the prefix
ca-to thepublisherId. The package will add it automatically. -
Ads.txt snippet
// package.json // ... "scripts": { "build": "next build && create-ads-txt", // 👈 if you want to create ads.txt automatically, recommended "create-ads-txt": "create-ads-txt" // 👈 if you want to create ads.txt manually }, // ...
[!WARNING]\ Your old
ads.txtwill be overwritten during the generation process.You must set
NEXT_PUBLIC_ADSENSE_PUBLISHER_IDas environment variable. The environment variable will be used to generate theads.txt.
If you decide to use Auto Ads, you are good to go. The ads will be automatically displayed on your page. (Setup Auto Ads)
Note
Google AdSense does't work in local environment. You need to test it in production or use Dummy Ads for Development.
import { AdUnit } from "next-google-adsense";
const Page = () => {
return (
<>
<AdUnit
publisherId="pub-XXXXXXXXXXXXXXXX" {/* 👈 16 digits */}
slotId="XXXXXXXXXX" {/* 👈 10 digits */}
layout="display" {/* See the API Reference for more options */}
/>
{/* or */}
<AdUnit {/* if NEXT_PUBLIC_ADSENSE_PUBLISHER_ID is set */}
slotId="XXXXXXXXXX"
layout="display"
/>
<YourContent />
</>
);
};
export default Page;Perfect for development and testing! Show realistic ad placeholders without needing actual AdSense approval.
import { AdUnit, DISPLAY_AD_SIZES, ARTICLE_AD_SIZES } from "next-google-adsense";
const Page = () => {
return (
<>
{/* Using predefined sizes */}
<AdUnit
slotId="1234567890"
layout="display"
dummySize="LEADERBOARD" {/* 728x90 */}
/>
<AdUnit
slotId="1234567890"
layout="in-article"
dummySize="MEDIUM_RECTANGLE" {/* 300x250 */}
/>
{/* Using custom dimensions */}
<AdUnit
slotId="1234567890"
layout="display"
dummySize={{ width: 600, height: 400 }}
/>
{/* Using size objects directly */}
<AdUnit
slotId="1234567890"
layout="display"
dummySize={DISPLAY_AD_SIZES.BANNER} {/* 468x60 */}
/>
<YourContent />
</>
);
};
export default Page;Note
Dummy ads only appear when the dummySize prop is provided. In production (when NODE_ENV/NEXT_PUBLIC_ENV is not "development"), real ads will be displayed instead.
<GoogleAdSense publisherId={string}>| Parameter | Optional | Type | Default | Description |
|---|---|---|---|---|
| publisherId | Yes | string | n/a | You can skip this parameter if you set the environment variable NEXT_PUBLIC_ADSENSE_PUBLISHER_ID. |
| isAutoAd | Yes | boolean | false | Whether to enable Auto Ads. |
| debug | Yes | boolean | false | Enable Google AdSense debug mode. |
<AdUnit publisherId={string} slotId={string} layout={"display" | "in-article" | "custom"} customLayout={JSX.Element} dummySize={DisplayAdSize | ArticleAdSize | {width: number, height: number}}>| Parameter | Optional | Type | Default | Description |
|---|---|---|---|---|
| publisherId | Yes | string | n/a | You can skip this parameter if you set the environment variable NEXT_PUBLIC_ADSENSE_PUBLISHER_ID. |
| slotId | No | string | n/a | Google AdSense Slot ID. |
| layout | Yes | "display" | "in-article" | "custom" | "display" | The layout of the AD. |
| customLayout | Yes | JSX.Element | n/a | The custom layout of the AD. This parameter is required if layout is set to "custom". |
| dummySize | Yes | DisplayAdSize | ArticleAdSize | {width: number, height: number} | n/a | Show dummy ad for development. Only appears when this prop is provided. |
All available ad sizes for the dummySize prop:
For layout="display" ads:
| Size Name | Key | Dimensions | Best For |
|---|---|---|---|
| Leaderboard | "LEADERBOARD" |
728 × 90 | Top of page, headers |
| Banner | "BANNER" |
468 × 60 | Above content |
| Half Banner | "HALF_BANNER" |
234 × 60 | Small horizontal spaces |
| Medium Rectangle | "MEDIUM_RECTANGLE" |
300 × 250 | Within content, sidebars |
| Large Rectangle | "LARGE_RECTANGLE" |
336 × 280 | Above the fold |
| Vertical Banner | "VERTICAL_BANNER" |
120 × 240 | Narrow sidebars |
| Wide Skyscraper | "WIDE_SKYSCRAPER" |
160 × 600 | Wide sidebars |
| Skyscraper | "SKYSCRAPER" |
120 × 600 | Narrow sidebars |
| Mobile Banner | "MOBILE_BANNER" |
320 × 50 | Mobile devices |
| Large Mobile Banner | "LARGE_MOBILE_BANNER" |
320 × 100 | Mobile devices, larger |
For layout="in-article" ads:
| Size Name | Key | Dimensions | Best For |
|---|---|---|---|
| Small Square | "SMALL_SQUARE" |
200 × 200 | Small content breaks |
| Square | "SQUARE" |
250 × 250 | Content breaks |
| Medium Rectangle | "MEDIUM_RECTANGLE" |
300 × 250 | Between paragraphs |
| Large Rectangle | "LARGE_RECTANGLE" |
336 × 280 | Longer content breaks |
import { AdUnit, DISPLAY_AD_SIZES, ARTICLE_AD_SIZES } from "next-google-adsense";
// Using predefined size keys
<AdUnit slotId="123" layout="display" dummySize="LEADERBOARD" />
<AdUnit slotId="456" layout="in-article" dummySize="SQUARE" />
// Using size objects
<AdUnit slotId="789" layout="display" dummySize={DISPLAY_AD_SIZES.BANNER} />
<AdUnit slotId="101" layout="in-article" dummySize={ARTICLE_AD_SIZES.MEDIUM_RECTANGLE} />
// Using custom dimensions
<AdUnit slotId="112" layout="display" dummySize={{ width: 400, height: 300 }} />No layout fits your needs? Let's create a custom layout.
Sample custom layout:
export const InFeedAd = () => {
return (
<ins
className="adsbygoogle"
style={{ display: "block" }}
data-ad-format="fluid"
data-ad-layout-key="<AD_LAYOUT_KEY>"
data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
data-ad-slot="XXXXXXXXXX"
/>
);
};Example (provided by Google AdSense):
<script
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXXXX"
crossorigin="anonymous"
></script>
<ins
class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout-key="<AD_LAYOUT_KEY>"
data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
data-ad-slot="XXXXXXXXXX"
></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>-
Remove all the
<script>tags. -
You will get the following html:
<ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="<AD_LAYOUT_KEY>" data-ad-client="ca-pub-XXXXXXXXXXXXXXXX" data-ad-slot="XXXXXXXXXX" > </ins>
-
Convert the html to JSX:
export const InFeedAd = () => { return ( <ins className="adsbygoogle" style={{ display: "block" }} data-ad-format="fluid" data-ad-layout-key="<AD_LAYOUT_KEY>" data-ad-client="ca-pub-XXXXXXXXXXXXXXXX" data-ad-slot="XXXXXXXXXX" /> ); };
-
Done! You can now use the custom layout in your app.
<AdUnit publisherId="<your-publisher-id>" slotId="<your-slot-id>" layout="custom" customLayout={InFeedAd}>
Full Code:
import { AdUnit } from "next-google-adsense";
export const InFeedAd = () => {
return (
<ins
className="adsbygoogle"
style={{ display: "block" }}
data-ad-format="fluid"
data-ad-layout-key="<AD_LAYOUT_KEY>"
data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
data-ad-slot="XXXXXXXXXX"
/>
);
};
const Page = () => {
return (
<>
<AdUnit
publisherId="pub-XXXXXXXXXXXXXXXX" {/* 👈 16 digits */}
slotId="XXXXXXXXXX" {/* 👈 10 digits */}
layout="custom"
customLayout={InFeedAd}
/>
<YourContent />
</>
);
};- Waiting for your report.
- Add custom layout validation.
Contributions are welcome! If you find a bug or have a feature request, please open an issue. If you want to contribute code, please fork the repository and submit a pull request.
Before you open a pull request, please make sure that you run npm run dev to make sure the code run as expected.
We are following Conventional Commits for commit messages.
This project is licensed under the MIT License - see the LICENSE file for details
Love it? Consider a donation to support my work.
