react-nextjs-adsense
v3.0.1
Published
A React and Next.js component for Google AdSense
Downloads
89
Maintainers
Readme
react-nextjs-adsense
A modern React component library for seamlessly integrating Google AdSense into your Next.js applications, with built-in ethical content filtering.
Demo: Click here to see the AdSense demo
Why Choose react-nextjs-adsense?
- Effortless Integration: Simple, declarative API designed specifically for Next.js apps
- Ethical Advertising: Built-in Islamic content filtering to ensure your ads align with ethical standards
- Consent-Ready: Supports Google's
pauseAdRequestsand non-personalised ads patterns for GDPR compliance - Developer-Friendly: Comprehensive TypeScript support and intuitive props
- Performance Optimized: Lazy-loads via IntersectionObserver to minimise impact on Core Web Vitals
Getting Started
Installation
# npm
npm install react-nextjs-adsense
# yarn
yarn add react-nextjs-adsense
# pnpm
pnpm add react-nextjs-adsense1. Add the AdSense script to your layout
Add the script once in your root layout. Google's generated ad code uses the ?client= query param and crossOrigin="anonymous" — use this exact form.
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta name="google-adsense-account" content="ca-pub-XXXXXXXXXXXXXXXX" />
<script
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXXXX"
crossOrigin="anonymous"
/>
</head>
<body>{children}</body>
</html>
);
}Note: Do not add a second copy of this script. The
<AdSense>component handles callingadsbygoogle.push({})itself — you do not need to do it in the layout.
Alternatively, use Next.js <Script> with strategy="afterInteractive" if you prefer to defer loading:
import Script from 'next/script';
<Script
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXXXX"
crossOrigin="anonymous"
strategy="afterInteractive"
/>2. Place an ad unit
"use client";
import { AdSense } from 'react-nextjs-adsense';
export default function BlogPost() {
return (
<article>
<h1>Blog Post Title</h1>
<AdSense
client="ca-pub-XXXXXXXXXXXXXXXX"
slot="1234567890"
format="auto"
responsive="true"
/>
<p>Your content here...</p>
</article>
);
}That's it. Ethical content filtering is automatically enabled.
Consent & Non-Personalised Ads
If you need to serve non-personalised ads to some users (e.g. users who have declined personalisation), pass consentState to the component. When personalisation is denied the component sets requestNonPersonalizedAds=1. When ad storage is denied entirely it uses pauseAdRequests=1 to hold the request until consent is updated.
import { AdSense, ConsentState } from 'react-nextjs-adsense';
// These values would come from your consent management solution
const consent: ConsentState = {
ad_storage: "granted", // "granted" | "denied"
ad_personalization: "granted", // "granted" | "denied"
};
<AdSense
client="ca-pub-XXXXXXXXXXXXXXXX"
slot="1234567890"
consentState={consent}
/>Behaviour by consent combination:
| ad_storage | ad_personalization | Result |
|---|---|---|
| "granted" | "granted" | Normal personalised ads |
| "granted" | "denied" | Non-personalised ads |
| "denied" | any | Ad request paused — no ad fires |
If you have a TCF-integrated CMP on the page that already handles NPA signalling, set tcfCompliant: true so the component does not double-signal:
const consent: ConsentState = {
ad_storage: "granted",
ad_personalization: "granted",
tcfCompliant: true,
};Component API
Props
| Prop | Type | Required | Default | Description |
|------|------|:--------:|---------|-------------|
| client | string | ✓ | — | Your AdSense publisher ID (ca-pub-XXXXXXXXXXXXXXXX) |
| slot | string | ✓ | — | Your ad unit ID |
| format | string | | 'auto' | Ad format ('auto', 'rectangle', 'vertical', 'fluid', etc.) |
| responsive | string | | 'false' | Set 'true' to make the ad adapt to container width |
| layout | string | | '' | Ad layout (e.g. 'in-article') |
| layoutKey | string | | '' | Layout key for customised ad formats |
| className | string | | '' | CSS class on the <ins> element |
| style | React.CSSProperties | | { display: 'block' } | Inline styles |
| pageLevelAds | boolean | | false | Enable Auto / page-level ads |
| adTest | string | | undefined | Set to "on" during development only — never in production |
| useIslamicGuidelines | boolean | | true | Enable Islamic-guidelines category blocklist |
| blockCategories | string[] | | [] | Additional ad categories to block |
| consentState | ConsentState | | undefined | Consent signals for non-personalised / paused ad handling |
ConsentState type
interface ConsentState {
ad_storage: "granted" | "denied";
ad_personalization: "granted" | "denied";
/** Set true if a TCF CMP is active and already handles NPA signalling */
tcfCompliant?: boolean;
}Ethical Content Filtering
Islamic-guidelines filtering is enabled by default. It automatically blocks 30+ ad categories using Google's setCategoryExclusion API.
Categories blocked by default include: dating, gambling, alcohol, tobacco, adult content, sex-related, interest-based loans (riba), speculative financial products (gharar), astrology, esoteric content, social casino, and more.
Add extra categories
<AdSense
client="ca-pub-XXXXXXXXXXXXXXXX"
slot="1234567890"
blockCategories={["fashion", "travel", "entertainment"]}
/>Disable Islamic filtering
<AdSense
client="ca-pub-XXXXXXXXXXXXXXXX"
slot="1234567890"
useIslamicGuidelines={false}
/>Integration Examples
App Router (Next.js 13+)
// app/blog/[slug]/page.tsx
"use client";
import { AdSense } from 'react-nextjs-adsense';
export default function BlogPost() {
return (
<article className="blog-content">
<h1>Blog Post Title</h1>
<AdSense
client="ca-pub-XXXXXXXXXXXXXXXX"
slot="1234567890"
responsive="true"
style={{ marginBottom: '2rem' }}
/>
<div className="article-content">
<p>Your content here...</p>
</div>
<AdSense
client="ca-pub-XXXXXXXXXXXXXXXX"
slot="9876543210"
responsive="true"
style={{ marginTop: '2rem' }}
/>
</article>
);
}Pages Router
// pages/index.tsx
import { AdSense } from 'react-nextjs-adsense';
export default function Home() {
return (
<main>
<AdSense
client="ca-pub-XXXXXXXXXXXXXXXX"
slot="1234567890"
format="auto"
responsive="true"
/>
</main>
);
}TypeScript Support
import {
AdSense,
ConsentState,
HaramCategory,
HARAM_AD_CATEGORIES,
} from 'react-nextjs-adsense';
const defaultCategories: readonly HaramCategory[] = HARAM_AD_CATEGORIES;
const consent: ConsentState = {
ad_storage: "granted",
ad_personalization: "denied",
};Best Practices
Script setup
- Load
adsbygoogle.jsonce per page in your root layout - Use the
?client=ca-pub-XXXXXXXXXXXXXXXXquery param — this is the format Google generates when you copy code from your AdSense account - Do not call
adsbygoogle.push({})in your layout; the<AdSense>component handles this
Ad placement
- Use
responsive="true"on all units to prevent layout shift - Keep to 3 or fewer ad units per page
- Place ads where they complement content rather than interrupt it
Development vs production
- Set
adTest="on"during development to simulate ads without real impressions - Remove
adTest(or leave itundefined) before deploying — leaving it on means no real revenue is earned
Troubleshooting
If ads aren't showing:
- Confirm your AdSense account is approved and the ad unit is active
- Disable your ad blocker — it affects test ads too
- Double-check your
clientandslotvalues - Confirm the
adsbygoogle.jsscript is present in the page<head> - Check the browser console for
adsbygoogleerrors
Further Resources
- Official Google AdSense Documentation
- Ad Personalization Settings & Code Examples
- Google's Ad Category Controls
- Next.js Documentation
License
MIT
Contributing
Issues and pull requests are welcome on GitHub.
