Skip to content

Commit b9c6121

Browse files
committed
feat: add dummy ad support for development and enhance ad unit functionality #20
1 parent c9a6914 commit b9c6121

8 files changed

Lines changed: 307 additions & 33 deletions

File tree

README.md

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Give me a ⭐ if you like it.
1515
- Support SSR (Server-Side Rendering), SSG (Static Site Generation) and CSR (Client-Side Rendering)
1616
- Support TypeScript
1717
- Zero Dependencies
18+
- Dummy Ad Support for Development - Preview ads locally without real AdSense integration
1819
- Theoretically support all AdSense AD types (see [🎨 Create a custom layout](#-create-a-custom-layout) for more details)
1920
- Create `ads.txt` automatically (see [Initialization / Verification](#initialization--verification-) for more details)
2021

@@ -28,10 +29,14 @@ Give me a ⭐ if you like it.
2829
- [Usage](#usage-)
2930
- [Auto Ads](#auto-ads)
3031
- [Manual Ads](#manual-ads)
32+
- [Dummy Ads for Development](#dummy-ads-for-development-)
3133
- [📖 API Reference](#-api-reference)
3234
- [Components](#components)
3335
- [GoogleAdSense](#initializes-the-google-adsense)
3436
- [AdUnit](#manual-ad)
37+
- [Ad Sizes](#ad-sizes)
38+
- [Display Ad Sizes](#display-ad-sizes)
39+
- [In-Article Ad Sizes](#in-article-ad-sizes)
3540
- [🎨 Create a custom layout](#-create-a-custom-layout)
3641
- [How to convert the given html to a custom layout?](#how-to-convert-the-given-html-to-a-custom-layout)
3742
- [🐛 Known Issues](#-known-issues)
@@ -125,6 +130,9 @@ If you decide to use Auto Ads, you are good to go. The ads will be automatically
125130

126131
#### Manual Ads
127132

133+
> [!NOTE]\
134+
> Google AdSense does't work in local environment. You need to test it in production or use [Dummy Ads for Development](#dummy-ads-for-development-).
135+
128136
```typescript
129137
import { AdUnit } from "next-google-adsense";
130138

@@ -150,6 +158,54 @@ const Page = () => {
150158
export default Page;
151159
```
152160

161+
#### Dummy Ads for Development 🧪
162+
163+
Perfect for development and testing! Show realistic ad placeholders without needing actual AdSense approval.
164+
165+
```typescript
166+
import { AdUnit, DISPLAY_AD_SIZES, ARTICLE_AD_SIZES } from "next-google-adsense";
167+
168+
const Page = () => {
169+
return (
170+
<>
171+
{/* Using predefined sizes */}
172+
<AdUnit
173+
slotId="1234567890"
174+
layout="display"
175+
dummySize="LEADERBOARD" {/* 728x90 */}
176+
/>
177+
178+
<AdUnit
179+
slotId="1234567890"
180+
layout="in-article"
181+
dummySize="MEDIUM_RECTANGLE" {/* 300x250 */}
182+
/>
183+
184+
{/* Using custom dimensions */}
185+
<AdUnit
186+
slotId="1234567890"
187+
layout="display"
188+
dummySize={{ width: 600, height: 400 }}
189+
/>
190+
191+
{/* Using size objects directly */}
192+
<AdUnit
193+
slotId="1234567890"
194+
layout="display"
195+
dummySize={DISPLAY_AD_SIZES.BANNER} {/* 468x60 */}
196+
/>
197+
198+
<YourContent />
199+
</>
200+
);
201+
};
202+
203+
export default Page;
204+
```
205+
206+
> [!NOTE]\
207+
> 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.
208+
153209
## 📖 API Reference
154210

155211
### Components
@@ -167,15 +223,65 @@ export default Page;
167223
#### Manual AD
168224

169225
```typescript
170-
<AdUnit publisherId={string} slotId={string} layout={"display" | "in-article" | "custom"} customLayout={JSX.Element}>
226+
<AdUnit publisherId={string} slotId={string} layout={"display" | "in-article" | "custom"} customLayout={JSX.Element} dummySize={DisplayAdSize | ArticleAdSize | {width: number, height: number}}>
171227
```
172228

173-
| Parameter | Optional | Type | Default | Description |
174-
| ------------ | -------- | ------------------------------------- | --------- | --------------------------------------------------------------------------------------------------- |
175-
| publisherId | Yes | string | n/a | You can skip this parameter if you set the environment variable `NEXT_PUBLIC_ADSENSE_PUBLISHER_ID`. |
176-
| slotId | No | string | n/a | Google AdSense Slot ID. |
177-
| layout | Yes | "display" \| "in-article" \| "custom" | "display" | The layout of the AD. |
178-
| customLayout | Yes | JSX.Element | n/a | The custom layout of the AD. This parameter is required if `layout` is set to "custom". |
229+
| Parameter | Optional | Type | Default | Description |
230+
| ------------ | -------- | --------------------------------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------- |
231+
| publisherId | Yes | string | n/a | You can skip this parameter if you set the environment variable `NEXT_PUBLIC_ADSENSE_PUBLISHER_ID`. |
232+
| slotId | No | string | n/a | Google AdSense Slot ID. |
233+
| layout | Yes | "display" \| "in-article" \| "custom" | "display" | The layout of the AD. |
234+
| customLayout | Yes | JSX.Element | n/a | The custom layout of the AD. This parameter is required if `layout` is set to "custom". |
235+
| dummySize | Yes | DisplayAdSize \| ArticleAdSize \| {width: number, height: number} | n/a | Show dummy ad for development. Only appears when this prop is provided. |
236+
237+
### Dummy Ad Sizes
238+
239+
All available ad sizes for the `dummySize` prop:
240+
241+
#### Display Ad Sizes
242+
243+
For `layout="display"` ads:
244+
245+
| Size Name | Key | Dimensions | Best For |
246+
| -------------------- | ---------------------- | ----------- | --------------------------- |
247+
| Leaderboard | `"LEADERBOARD"` | 728 × 90 | Top of page, headers |
248+
| Banner | `"BANNER"` | 468 × 60 | Above content |
249+
| Half Banner | `"HALF_BANNER"` | 234 × 60 | Small horizontal spaces |
250+
| Medium Rectangle | `"MEDIUM_RECTANGLE"` | 300 × 250 | Within content, sidebars |
251+
| Large Rectangle | `"LARGE_RECTANGLE"` | 336 × 280 | Above the fold |
252+
| Vertical Banner | `"VERTICAL_BANNER"` | 120 × 240 | Narrow sidebars |
253+
| Wide Skyscraper | `"WIDE_SKYSCRAPER"` | 160 × 600 | Wide sidebars |
254+
| Skyscraper | `"SKYSCRAPER"` | 120 × 600 | Narrow sidebars |
255+
| Mobile Banner | `"MOBILE_BANNER"` | 320 × 50 | Mobile devices |
256+
| Large Mobile Banner | `"LARGE_MOBILE_BANNER"` | 320 × 100 | Mobile devices, larger |
257+
258+
#### In-Article Ad Sizes
259+
260+
For `layout="in-article"` ads:
261+
262+
| Size Name | Key | Dimensions | Best For |
263+
| ---------------- | -------------------- | ---------- | ---------------------------- |
264+
| Small Square | `"SMALL_SQUARE"` | 200 × 200 | Small content breaks |
265+
| Square | `"SQUARE"` | 250 × 250 | Content breaks |
266+
| Medium Rectangle | `"MEDIUM_RECTANGLE"` | 300 × 250 | Between paragraphs |
267+
| Large Rectangle | `"LARGE_RECTANGLE"` | 336 × 280 | Longer content breaks |
268+
269+
#### Usage Examples
270+
271+
```typescript
272+
import { AdUnit, DISPLAY_AD_SIZES, ARTICLE_AD_SIZES } from "next-google-adsense";
273+
274+
// Using predefined size keys
275+
<AdUnit slotId="123" layout="display" dummySize="LEADERBOARD" />
276+
<AdUnit slotId="456" layout="in-article" dummySize="SQUARE" />
277+
278+
// Using size objects
279+
<AdUnit slotId="789" layout="display" dummySize={DISPLAY_AD_SIZES.BANNER} />
280+
<AdUnit slotId="101" layout="in-article" dummySize={ARTICLE_AD_SIZES.MEDIUM_RECTANGLE} />
281+
282+
// Using custom dimensions
283+
<AdUnit slotId="112" layout="display" dummySize={{ width: 400, height: 300 }} />
284+
```
179285

180286
## 🎨 Create a custom layout
181287

@@ -198,7 +304,7 @@ export const InFeedAd = () => {
198304
};
199305
```
200306

201-
#### How to convert the given html to a custom layout?
307+
### How to convert the given html to a custom layout?
202308

203309
Example (provided by Google AdSense):
204310

package-lock.json

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,8 @@
4747
},
4848
"bin": {
4949
"create-ads-txt": "./bin/cli.mjs"
50+
},
51+
"dependencies": {
52+
"assert-never": "^1.4.0"
5053
}
5154
}

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/AdLayout.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { DetailedHTMLProps } from "react";
22
// biome-ignore lint/style/useImportType: needed in the <ins> tag
33
import React from "react";
4+
import { DummyAd } from "./DummyAd";
5+
import { isDevelopment } from "./utils";
46

57
export type Layout = "display" | "in-article" | "custom";
68

@@ -11,6 +13,7 @@ interface AdLayoutProps
1113
> {
1214
dataAdClient: string;
1315
dataAdSlot: string;
16+
dummySize?: { width: number; height: number };
1417
}
1518

1619
interface DisplayProps extends AdLayoutProps {
@@ -21,8 +24,13 @@ export const Display = ({
2124
responsive,
2225
dataAdClient,
2326
dataAdSlot,
27+
dummySize,
2428
...props
2529
}: DisplayProps) => {
30+
if (dummySize && isDevelopment()) {
31+
return <DummyAd size={dummySize} {...props} />;
32+
}
33+
2634
return (
2735
<ins
2836
className="adsbygoogle"
@@ -41,8 +49,13 @@ interface InArticleProps extends AdLayoutProps {}
4149
export const InArticle = ({
4250
dataAdClient,
4351
dataAdSlot,
52+
dummySize,
4453
...props
4554
}: InArticleProps) => {
55+
if (dummySize && isDevelopment()) {
56+
return <DummyAd size={dummySize} {...props} />;
57+
}
58+
4659
return (
4760
<ins
4861
className="adsbygoogle"

0 commit comments

Comments
 (0)