Reputation: 2470
I am beginner in reactjs and I want to embed google inline ads in loops. The ad is showing only at first time. When I inspect the element tag shows in loop. Can I please know how to solve this issue?
Google adsense code:-
var ScheduleRow = React.createClass({
var rows = _.map(scheduleData.schedules, function(scheduleList, i) {
var divStyle = { display: "block"};
return (
<ins className="adsbygoogle"
style={divStyle}
data-ad-client="ca-pub-3199660652950290"
data-ad-slot="6259591966"
data-ad-format="auto" key={i}>
</ins>
);
});
return (
<span>
{rows}
</span>
);
});
Output:-
Inspect Element Output:-
Upvotes: 25
Views: 55038
Reputation: 482
If you have the Adsense script loading in one component and ad slot it another, the script might not have loaded while the second component is mounted. Due to this, window.adsbygoogle
will be evaluated to [] and the ad will not load. This will even affect the auto ads if you are using both auto ads and ad units.
This is the solution I have implemented:
import React, { useEffect } from "react"
const SideAd = () => {
useEffect(() => {
const pushAd = () => {
try {
const adsbygoogle = window.adsbygoogle
console.log({ adsbygoogle })
adsbygoogle.push({})
} catch (e) {
console.error(e)
}
}
let interval = setInterval(() => {
// Check if Adsense script is loaded every 300ms
if (window.adsbygoogle) {
pushAd()
// clear the interval once the ad is pushed so that function isn't called indefinitely
clearInterval(interval)
}
}, 300)
return () => {
clearInterval(interval)
}
}, [])
return (
<ins
className="adsbygoogle"
style={{ display: "inline-block", width: "300px", height: "250px" }}
data-ad-client="ca-pub-xxxxxx"
data-ad-slot="xxxxx"
></ins>
)
}
export default SideAd
Upvotes: 6
Reputation: 780
This seems a duplicated question. You can find it in here. But I think it isn't 100% clear. So, I came across once with this blog post which is more clear.
From Google you have this:
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
</script>
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-12121212"
data-ad-slot="12121212"
data-ad-format="auto"/>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
Now, in your react app:
Include the following snippet in your index.html
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
Create your react component like:
import React from 'react';
export default class AdComponent extends React.Component {
componentDidMount () {
(window.adsbygoogle = window.adsbygoogle || []).push({});
}
render () {
return (
<ins className='adsbygoogle'
style={{ display: 'block' }}
data-ad-client='ca-pub-12121212'
data-ad-slot='12121212'
data-ad-format='auto' />
);
}
}
Now, to render it multiple times you can simply wrap the ins
html tag with an iterator like map
. However, I don't fully understand your need here.
If you want to show them all at once, then do your map like this.
If you want to randomise your ad, add a state to your component and a tick state so that it can re-render every X seconds. Check it in this SO answer
Notes:
class
attribute to className
style
attribute to be wrapped like this: style={{ display: 'block' }}
Upvotes: 45
Reputation: 469
Answer by @jpgbarbosa is great. I'll add better practice for Server Side Rendered React applications which have multiple pages, for scalability, I suggest you use this method to keep code base maintainable.
export default class HomePage extends React.Component {
componentDidMount() {
const installGoogleAds = () => {
const elem = document.createElement("script");
elem.src =
"//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
elem.async = true;
elem.defer = true;
document.body.insertBefore(elem, document.body.firstChild);
};
installGoogleAds();
(adsbygoogle = window.adsbygoogle || []).push({});
}
render() {
return (
<ins className='adsbygoogle'
style={{ display: 'block' }}
data-ad-client='ca-pub-12121212'
data-ad-slot='12121212'
data-ad-format='auto' />
);
}
}
Upvotes: 5