- 🎯 Plug-and-play - Configure em menos de 5 minutos
- ⚡ Lazy Loading automático com Intersection Observer
- 🔄 Auto-refresh de anúncios configurável
- 🎨 TypeScript com tipagem completa
- 📱 Mobile-first e responsivo
- 🛡️ Memory management automático
- 🔧 Bidders pré-configurados (Amazon, Rubicon, AppNexus, etc.)
npm install react-ads-sdk
# ou
yarn add react-ads-sdkNext.js (pages/_app.tsx):
import { AdProvider } from 'react-ads-sdk';
export default function MyApp({ Component, pageProps }) {
return (
<AdProvider config={{
publisherId: 'ca-pub-XXXXXXXXXXXXXXXX', // Seu Google Ad Manager ID
prebidTimeout: 2000,
enableLazyLoad: true,
testMode: process.env.NODE_ENV === 'development'
}}>
<Component {...pageProps} />
</AdProvider>
);
}React (src/App.tsx):
import { AdProvider } from 'react-ads-sdk';
function App() {
return (
<AdProvider config={{
publisherId: 'ca-pub-XXXXXXXXXXXXXXXX',
prebidTimeout: 2000,
enableLazyLoad: true
}}>
<div className="App">
{/* Sua aplicação */}
</div>
</AdProvider>
);
}import { AdSlot } from 'react-ads-sdk';
export default function HomePage() {
const bannerSlot = {
id: 'banner-top',
path: '/1234567/homepage/banner', // Seu ad unit path
sizes: [[728, 90], [970, 250]] // Tamanhos do anúncio
};
return (
<div>
<h1>Minha Página</h1>
<AdSlot slot={bannerSlot} lazyLoad />
</div>
);
}import { AdSlot, BidderPresets } from 'react-ads-sdk';
export default function HomePage() {
const bannerSlot = {
id: 'banner-prebid',
path: '/1234567/homepage/banner',
sizes: [[728, 90], [970, 250]],
targeting: { section: 'homepage' }
};
const bidders = [
BidderPresets.rubicon({
accountId: '12345',
siteId: '67890',
zoneId: '54321'
}),
BidderPresets.appnexus({
placementId: '13144370'
}),
BidderPresets.amazon({
slotID: 'homepage-banner'
})
];
return (
<AdSlot
slot={bannerSlot}
bidders={bidders}
lazyLoad
refreshInterval={60000} // Auto-refresh a cada 60s
/>
);
}// Desktop
const desktopBanner = {
sizes: [
[728, 90], // Leaderboard
[970, 250], // Billboard
[300, 250], // Medium Rectangle
[336, 280] // Large Rectangle
]
};
// Mobile
const mobileBanner = {
sizes: [
[320, 50], // Mobile Banner
[320, 100], // Large Mobile Banner
[300, 250] // Mobile Rectangle
]
};import { BidderPresets } from 'react-ads-sdk';
// Amazon A9
BidderPresets.amazon({ slotID: 'banner-1' })
// Rubicon Project
BidderPresets.rubicon({ accountId: '123', siteId: '456', zoneId: '789' })
// AppNexus
BidderPresets.appnexus({ placementId: '12345' })
// Index Exchange
BidderPresets.ix({ siteId: 'site-123', size: [728, 90] })
// OpenX
BidderPresets.openx({ unit: 'unit-123', delDomain: 'domain.openx.net' })
// PubMatic
BidderPresets.pubmatic({ publisherId: 'pub-123', adSlot: 'slot-name' })const advancedConfig = {
publisherId: 'ca-pub-XXXXXXXXXXXXXXXX', // OBRIGATÓRIO
prebidTimeout: 2000, // Timeout do leilão Prebid
enableLazyLoad: true, // Lazy loading automático
refreshInterval: 60000, // Auto-refresh global (mín. 30s)
testMode: false // Debug mode (só dev!)
};interface AdSlotProps {
slot: AdSlotType; // Configuração do slot (obrigatório)
bidders?: PrebidBidder[]; // Array de bidders Prebid
lazyLoad?: boolean; // Lazy loading (padrão: false)
refreshInterval?: number; // Auto-refresh em ms (mín. 30000)
className?: string; // CSS class
style?: React.CSSProperties; // Inline styles
onLoad?: () => void; // Callback quando carrega
onError?: (error: Error) => void; // Callback de erro
}import { useAd } from 'react-ads-sdk';
function CustomComponent() {
const { adService } = useAd();
const refreshAd = () => {
adService?.refreshAd('banner-id');
};
const setTargeting = () => {
adService?.setTargeting('category', 'tech');
};
return (
<div>
<button onClick={refreshAd}>Refresh Anúncio</button>
<button onClick={setTargeting}>Set Targeting</button>
</div>
);
}- Sempre use o
AdProviderno ponto de entrada (_app.tsx) - Configure Publisher ID válido no Google Ad Manager
- Use tamanhos padrão IAB para melhor compatibilidade
- Ative lazy loading para anúncios abaixo da dobra
- Defina refresh mínimo de 30 segundos
- Não deixe
testMode: trueem produção - Não use refresh menor que 30 segundos
- Não inicialize o serviço em múltiplos lugares
- Não ignore tratamento de erros
- Verifique o Publisher ID - Deve estar no formato
ca-pub-XXXXXXXXXXXXXXXX - Confirme o ad unit path - Formato:
/network-id/ad-unit-name - Teste sem lazy loading primeiro
- Abra o console para verificar erros
Adicione ao next.config.js:
async headers() {
return [{
source: '/(.*)',
headers: [{
key: 'Content-Security-Policy',
value: "script-src 'self' 'unsafe-inline' *.doubleclick.net *.googlesyndication.com *.amazon-adsystem.com"
}]
}]
}// pages/_app.tsx
import { AdProvider } from 'react-ads';
export default function MyApp({ Component, pageProps }) {
return (
<AdProvider config={{
publisherId: 'ca-pub-1234567890123456',
prebidTimeout: 2000,
enableLazyLoad: true,
testMode: false
}}>
<Component {...pageProps} />
</AdProvider>
);
}
// components/HomePage.tsx
import { AdSlot, BidderPresets } from 'react-ads';
export default function HomePage() {
const headerBanner = {
id: 'header-banner',
path: '/1234567/homepage/header',
sizes: [[728, 90], [970, 250]],
targeting: { section: 'home', category: 'tech' }
};
const sidebarBanner = {
id: 'sidebar-banner',
path: '/1234567/homepage/sidebar',
sizes: [[300, 250], [336, 280]]
};
const bidders = [
BidderPresets.rubicon({
accountId: '12345',
siteId: '67890',
zoneId: '54321'
}),
BidderPresets.amazon({
slotID: 'homepage'
})
];
return (
<div>
<header>
<AdSlot
slot={headerBanner}
bidders={bidders}
onLoad={() => console.log('Header banner loaded')}
/>
</header>
<main>
<h1>Conteúdo Principal</h1>
</main>
<aside>
<AdSlot
slot={sidebarBanner}
bidders={bidders}
lazyLoad
refreshInterval={90000}
/>
</aside>
</div>
);
}Totalmente tipado com TypeScript:
import type { AdConfig, AdSlotType, PrebidBidder } from 'react-ads';
const config: AdConfig = {
publisherId: 'ca-pub-1234567890123456',
prebidTimeout: 2000,
enableLazyLoad: true
};
const slot: AdSlotType = {
id: 'my-banner',
path: '/1234567/homepage/banner',
sizes: [[728, 90]]
};MIT © Luis Hoshina
⚡ Comece a monetizar sua aplicação React/Next.js em minutos!
Se este pacote te ajudou, considere dar uma ⭐ no repositório!