Troubleshooting Guide
This document covers common issues with AdSense integration and how to resolve them.
Common Errors
Error: "All 'ins' elements already have ads in them"
TagError: adsbygoogle.push() error: All 'ins' elements in the DOM
with class=adsbygoogle already have ads in them.
Cause: push({}) was called on an <ins> element that already has an ad.
When it happens:
- React Router navigation (component remounts)
- React StrictMode (double-mounting in development)
- Multiple
push()calls for the same element
Solution: Check data-ad-status before calling push():
useEffect(() => {
// Check if already processed
if (adRef.current?.dataset?.adStatus) {
return // Skip - already has an ad
}
(window.adsbygoogle = window.adsbygoogle || []).push({})
}, [])
Ads Not Showing in Production
Symptoms:
- Blank space where ad should be
- No network requests to googlesyndication.com
- No errors in console
Checklist:
-
Check environment variable:
# In browser console
console.log(import.meta.env.VITE_ADSENSE_PUBLISHER_ID)Should show
ca-pub-XXXXXXXX -
Check script loaded:
# In browser console
typeof window.adsbygoogleShould return
"object", not"undefined" -
Check ad unit exists in AdSense:
- Log into AdSense Dashboard
- Verify the slot ID exists and is active
-
Check for ad blockers:
- Disable ad blockers temporarily
- Try in incognito mode
Blank Space When Ad Doesn't Fill
Symptoms: Empty space where ad should be (ad unit unfilled)
Cause: AdSense couldn't find an ad to show
Solution: Our CSS should hide unfilled ads automatically:
.ad-sense-wrapper:has(ins.adsbygoogle[data-ad-status="unfilled"]) {
display: none !important;
}
If still showing blank space:
- Check if CSS is loaded (inspect element)
- Verify the wrapper has class
ad-sense-wrapper - Check browser support for
:has()selector
Browser support for :has():
- Chrome 105+ (Sep 2022)
- Safari 15.4+ (Mar 2022)
- Firefox 121+ (Dec 2023)
- Edge 105+ (Sep 2022)
Wrong Ad Size Displayed
Symptoms: Ad appears at wrong dimensions
Possible causes:
-
Using in-article ad for banner placement:
- In-article ads are fluid, not fixed-size
- Use Display ads for fixed dimensions
-
CSS class not applied:
// Make sure responsiveClass is passed
<AdSenseUnit
slot={AD_SENSE_UNITS.HOME_HERO}
responsiveClass="ad-sense-horizontal-banner" // Required
/> -
data-ad-format still present: When using
responsiveClass, we should NOT havedata-ad-format:// This is handled automatically, but verify in DevTools
{ ...(!useResponsiveClass && { 'data-ad-format': format }) }
Placeholder Shows in Production
Symptoms: See "Google AdSense Placeholder" in production
Cause: VITE_ADSENSE_PUBLISHER_ID is not set or empty
Solution:
-
Check deployment configuration:
# deploy/deploy.yml
env:
VITE_ADSENSE_PUBLISHER_ID:
- VITE_ADSENSE_PUBLISHER_ID -
Check Dockerfile:
ARG VITE_ADSENSE_PUBLISHER_ID
ENV VITE_ADSENSE_PUBLISHER_ID=$VITE_ADSENSE_PUBLISHER_ID -
Verify the secret is set in your deployment platform
CLS (Cumulative Layout Shift) Issues
Symptoms: Content jumps when ad loads
Cause: Space not reserved before ad loads
Solution: Always specify minHeight:
// For fluid ads
<AdSenseUnit
slot={AD_SENSE_UNITS.HOME_AFTER_HERO}
format="fluid"
layout="in-article"
minHeight="100px" // Reserve space
/>
// For responsive banners (CSS handles it)
<AdSenseUnit
slot={AD_SENSE_UNITS.HOME_HERO}
responsiveClass="ad-sense-horizontal-banner"
// minHeight not needed - CSS sets dimensions
/>
Debugging Tools
Check Ad Status in Console
// Find all ad slots and their status
document.querySelectorAll('ins.adsbygoogle').forEach((ins, i) => {
console.log(`Ad ${i}:`, {
slot: ins.dataset.adSlot,
status: ins.dataset.adStatus,
client: ins.dataset.adClient
})
})
Check if AdSense Script Loaded
// Should return an array
console.log(window.adsbygoogle)
// Check if it's the real AdSense (not just our fallback array)
console.log(window.adsbygoogle.loaded) // true if script loaded
Force Placeholder in Production (Testing)
Temporarily use PLACEHOLDER slot to test placeholder rendering:
<AdSenseUnit
slot={AD_SENSE_UNITS.PLACEHOLDER} // Forces placeholder
minHeight="100px"
/>
Environment-Specific Issues
Development
| Issue | Solution |
|---|---|
| Want to see real ads | Can't - AdSense has no sandbox. Use production. |
| Placeholder not showing | Check slot is not PLACEHOLDER constant |
| Console errors about adsbygoogle | Expected when publisher ID not set |
QA
| Issue | Solution |
|---|---|
| Need to test ad behavior | Deploy to production with test page |
| Placeholder dimensions wrong | Pass minHeight or responsiveClass |
Production
| Issue | Solution |
|---|---|
| Low fill rate | Use standard IAB sizes (320x50, 728x90, etc.) |
| Ads loading slowly | Normal - ads are loaded asynchronously |
| Revenue not tracking | Create separate ad units per placement |
Google AdSense Dashboard Issues
Ad Unit Not Showing
- Wait 10-15 minutes after creating new ad unit
- Verify site is approved in AdSense
- Check ad unit is not paused
Low Fill Rate
- Use standard IAB ad sizes
- Check placement isn't too intrusive (policy violation)
- Verify traffic quality
Policy Violation Warnings
- Never click your own ads
- Don't encourage users to click ads
- Don't place ads on pages with prohibited content
- Ensure ads are clearly distinguishable from content
Quick Reference
Ad Unit Types
| Type | Best For | Format Prop | Layout Prop |
|---|---|---|---|
| Display (Responsive) | Banners, fixed positions | 'auto' or use responsiveClass | - |
| In-Article | Between content | 'fluid' | 'in-article' |
| In-Feed | Within lists | 'fluid' | 'in-feed' |
Standard Sizes (Best Fill Rates)
| Mobile | Tablet | Desktop |
|---|---|---|
| 320x50 | 468x60 | 728x90 |
| 320x100 | 300x250 | 970x90 |
| 300x250 | 336x280 | 300x250 |