Tuesday, May 27, 2014

How I use Google AdSense and Google Analytics with Meteor websites

Here is how I managed to get Google AdSense and Google Analytics into my Meteor websites: airbnbconfessions and NoMorePasswordsJustEmail.

Google Analytics is easy

It's not difficult getting Google Analytics into your Meteor web app. Simply take the Google Analytics startup code and put it in client-side of your Meteor source.

Here, for example, is a file I have within the /client directory of my Meteor airbnbconfessions source code.

Meteor.startup(function() {
    $(document).ready(function() {
        // show google analytics if running on the live web site
        if ( -1 != document.URL.indexOf("www.airbnbconfessions.com") )
        {
            (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

            ga('create', 'UA-YOUR-CODE-HERE', 'airbnbconfessions.com');
            ga('send', 'pageview');
        }
    });
});

Note that I rely on jQuery and $(document).ready() but I assume Meteor.startup() probably would work as well.

Google Adsense is trickier

Two problems: 1) Meteor really wants to be in controls of rendering all your HTML, and 2) Google really wants the page to exists as some raw HTML before rendering the ads.

For (1), Meteor provides the /public directory. Anything in /public bypassed the Meteor rendering system and is just available to the web client like any other raw internet file.

For (2), the ads will be loaded within iframes, refereing to those /public files, from the main page.

Bringing Google Adsense and Meteor together

In NoMorePasswordsJustEmail, I want the ads to appear in the right for web browsers, but on the bottom for mobile browsers. So in my primary index.html file uses bootstrap classes in this code:

<div id="list-stuff">
      <div class="row">

        <div class="span9">

          ...page stuff...

        </div>

        <div class="span3 hidden-phone" style="text-align:center;">
          <center>
            {{> adsRight}}
          </center>
        </div>
      </div>

      <div class="row visible-phone" style="margin-left:-20px;margin-right:-20px;">{{! style makes up for 20 pixels added to body }}
        <div class="span10" style="text-align:center;">
          <center>
            {{> adsBottom}}
          </center>
        </div>
      </div>

    </div>

Those adsright and adsbottom templates render iframes that will load the files that were in  /public and look like this client/ads.html file.

<!-- google ads stuff -->
<!-- http://stackoverflow.com/questions/14389766/meteor-js-use-external-script -->
  <template name="adsRight">
    <div id="adsRight">
      <iframe src="/adright.html?v={{{unique}}}" seamless width="160" height="600" scrolling="no"
       frameborder="0" marginheight="0" marginwidth="0"
       style="margin:0;padding:0;border:none;width:160px;height:600px"></iframe>
    </div>
  </template>
  <template name="adsBottom">
    <div id="adsBottom">
      <hr/>
      <iframe src="/adbottom.html?v={{{unique}}}" seamless width="336" height="280" scrolling="no"
       frameborder="0" marginheight="0" marginwidth="0"
       style="margin:0;padding:0;border:none;width:336px;height:280px"></iframe>
    </div>
  </template>

That code refers to unique, just force Google to take a moment to check the text on the page each time, and provide a fresh ad as the text of the page changes with new reloads. client/ads.js provides that:

Template.adsRight.unique = function() {
    return (new Date()).valueOf();
};

Template.adsBottom.unique = function() {
    return (new Date()).valueOf();
};

Finally, the two files that like to the ads themselves.

public/adbottom.html:

<html>
<head>
<style type="text/css">
* {
    margin: 0;
    padding: 0;
}
</style>
</head>
<body>
<div>

<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- nmpjebottom -->
<ins class="adsbygoogle"
     style="display:inline-block;width:336px;height:280px"
     data-ad-client="ca-pub-YOUR-GOOGLE-CODE"
     data-ad-slot="YOUR-GOOGLE-ADSLOT"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

</div>
</body>
</html>

public/adright.html:

<html>
<head>
<style type="text/css">
* {
    margin: 0;
    padding: 0;
}
</style>
</head>
<body>
<div>

<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- nmpjeright -->
<ins class="adsbygoogle"
     style="display:inline-block;width:160px;height:600px"
     data-ad-client="ca-pub-YOUR-GOOGLE-CODE"
     data-ad-slot="YOUR-GOOGLE-ADSLOT"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

</div>
</body>
</html>

That's all.

Good luck. My fingers are crossed for you.

5 comments:

  1. How did you get accepted to adwords with a meteor site in the first place? My site was rejected. I thought it was due to being a meteor site which is js based

    ReplyDelete
    Replies
    1. I wrote "Adwords" (which is Google's way to pay to place ads on pages) a couple of times when I meant "AdSense" (which is Google's way to get paid for ads). I'm sorry about that (I have since corrected those two instance, but I'm stuck with "adwords" in the URL).

      Even with AdSense, I'm not sure if, technically I'm within Google's rules for AdSense, which are kind of complicated and make it unclear about ads in non-static pages, or within frames of such pages. The reason the above works, I think, is that the adsense code shows up later than the rest of the page.

      If someone at Google is reading this comment, and decides that I am violating their rules, they will probably terminate my adsense account, which I use on a few blogs. That will mean I lose out on $1 per month in AdSense revenue, meaning I will be able to buy 1/2 less cups of coffee per month, which is not a tragedy.

      Delete
  2. not sure what I did wrong, by I still get adsense code blocked by client

    ReplyDelete
    Replies
    1. Hmmph. Can you verify that the late "unique" code is running (perhaps by putting something other than the google code there, maybe an alert()?) Also, are any of the sites I used as an example working for you, for instance: airbnbconfessions.com?

      Delete
    2. Are you using an Ad blocker?

      Delete