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.