23

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:-

Output Image

Inspect Element Output:-

Inspect Element output

Trect
  • 2,759
  • 2
  • 30
  • 35
Sharma Vikram
  • 2,440
  • 6
  • 23
  • 46

3 Answers3

45

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:

  1. From you google sense add, rename class attribute to className
  2. Update style attribute to be wrapped like this: style={{ display: 'block' }}
Joshua
  • 3,055
  • 3
  • 22
  • 37
jpgbarbosa
  • 780
  • 4
  • 14
  • sorry for late reply, i'm not feeling well since last 2 weeks, today i'll implement – Sharma Vikram Sep 16 '17 at 14:22
  • i want to show ads in a loop but it shows only first row – Sharma Vikram Sep 16 '17 at 15:10
  • 1
    I am doing this same thing. still I don't see ad. I have created a new component for ads and imported this in my Home.jsx file. When I do inspect, in cosole tab it shows error:` Failed to load the resource : ads.js` – Reema Parakh Feb 26 '19 at 08:03
5

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' />
    );
  }
}
jwpfox
  • 5,124
  • 11
  • 45
  • 42
5

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
Abhishek E H
  • 479
  • 2
  • 7
  • 14