Robby on Rails: Tracking Google Analytics events in development environment with GoogleAnalyticsProxythoughts.sort_by{|t| t[:topic]}.collect tag:www.robbyonrails.com,2005:TypoTypo2009-11-01T14:01:04-05:00Robby Russellurn:uuid:e2bd1653-794b-473a-89ed-a89a58eb07062009-11-01T13:55:00-05:002009-11-01T14:01:04-05:00Tracking Google Analytics events in development environment with GoogleAnalyticsProxy<p>As mentioned in a recent article<sup><a href="#fn1">1</a></sup>, I’ve been diving deep into <a href="http://www.google.com/analytics/">Google Analytics</a> lately while working on a few client projects. We’re aiming to use much more of the features of Google Analytics and have been hitting some roadblocks with the development versus production application environments. Once you begin to dive into event tracking and <span class="caps">AJAX</span>-driven goal conversions, relying on just the sample code that Google Analytics provides you is going to result in you looking at a handful of JavaScript errors.</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfu1f/pagetracker-is-not-defined"><img src="http://img.skitch.com/20091101-c62euttfs5ejejt2eqpfxpnfau.preview.jpg" alt="pageTracker is not defined" /></a></div>
<p>another example from the firebug javascript console…</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfu1g/firebug-pagetracker-is-not-defined"><img src="http://img.skitch.com/20091101-p5mb21ufih99n3sa6uafsc4gyf.preview.jpg" alt="firebug pageTracker is not defined" /></a></div>
<p>We see JavaScript errors like this because we don’t load the google analytics code in our development environments. As you can see, we are only loading this in our production environment.</p>
<div class="typocode"><pre><code class="typocode_ruby "> <span class="punct"><%</span> <span class="keyword">if</span> <span class="constant">RAILS_ENV</span> <span class="punct">==</span> <span class="punct">'</span><span class="string">production</span><span class="punct">'</span> <span class="punct">-%></span><span class="string">
<!--// Google Analytics //--</span><span class="punct">></span>
<span class="punct"><</span><span class="ident">script</span> <span class="ident">type</span><span class="punct">="</span><span class="string">text/javascript</span><span class="punct">"></span>
<span class="ident">var</span> <span class="ident">gaJsHost</span> <span class="punct">=</span> <span class="punct">(("</span><span class="string">https:</span><span class="punct">"</span> <span class="punct">==</span> <span class="ident">document</span><span class="punct">.</span><span class="ident">location</span><span class="punct">.</span><span class="ident">protocol</span><span class="punct">)</span> <span class="punct">?</span> <span class="punct">"</span><span class="string">https://ssl.</span><span class="punct">"</span> <span class="punct">:</span> <span class="punct">"</span><span class="string">http://www.</span><span class="punct">");</span>
<span class="ident">document</span><span class="punct">.</span><span class="ident">write</span><span class="punct">(</span><span class="ident">unescape</span><span class="punct">("</span><span class="string">%3Cscript src='</span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">gaJsHost</span> <span class="punct">+</span> <span class="punct">"</span><span class="string">google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E</span><span class="punct">"));</span>
<span class="punct"></</span><span class="regex">script>
<script type="text</span><span class="punct">/</span><span class="ident">javascript</span><span class="punct">"</span><span class="string">>
var pageTracker = _gat._getTracker(</span><span class="punct">"</span><span class="constant">UA</span><span class="punct">-</span><span class="constant">XXXXXX</span><span class="punct">-</span><span class="number">1</span><span class="punct">"</span><span class="string">);
pageTracker._trackPageview();
</script>
<% end -%></span></code></pre></div>
<p>To <a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiEventTracking.html#_gat.GA_EventTracker_._trackEvent">track an event with Google Analytics</a>, you’d need to trigger something like:</p>
<div class="typocode"><pre><code class="typocode_ruby "> <span class="ident">pageTracker</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Button</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Click</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Get in touch</span><span class="punct">');</span></code></pre></div>
<p>As you can see from our code earlier, in development, the <code>pageTracker</code> variable isn’t defined and that’s why we’re getting those JS errors. We also don’t want to add conditionals everywhere in our application to check if we’re in development or production environment.. as that’d just make our views uglier than they need to be. So, I decided that I’d create a proxy class in JavaScript that would allow us to trigger <code>_trackEvent()</code> and <code>_trackPageview()</code> and handle it appropriately.</p>
<p>This class works with the following logic:</p>
<ul>
<li>if google analytics <strong>is</strong> loaded, pass the parameters to the real <code>pageTracker</code></li>
<li>if google analytics <strong>is <span class="caps">NOT</span></strong> loaded, output the information to <code>console.log()</code> for debugging purposes</li>
</ul>
<p>For example, on a gallery on our web site… we track when people navigate next and/or previous through the photos. In our development environment, I can watch the JavaScript console output the following:</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfu19/firebug-gap"><img src="http://img.skitch.com/20091101-jwbyprqyaj68hxtjw8bbg6mccm.preview.jpg" alt="Firebug - GAP" /></a></div>
<p>And in our production environment, we can see that this was sent to Google Analytics.</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfuut/firebug-trackevent"><img src="http://img.skitch.com/20091101-q9dkn8tw3kyndxr55fqed6k8fq.preview.jpg" alt="Firebug - trackEvent()" /></a></div>
<p>We’re able to do this by initializing the GoogleAnalyticsProxy class and calling these functions through it. For example:</p>
<div class="typocode"><pre><code class="typocode_ruby "> <span class="ident">_gap</span> <span class="punct">=</span> <span class="ident">new</span> <span class="constant">GoogleAnalyticsProxy</span><span class="punct">();</span>
<span class="ident">_gap</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Video</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Play</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Homepage video</span><span class="punct">');</span>
<span class="ident">_gap</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Video</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Pause</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Homepage video</span><span class="punct">');</span>
<span class="ident">_gap</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Button</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Click</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Call to action X</span><span class="punct">');</span></code></pre></div>
<p>You’ll see that we’re just calling <code>_gap</code> versus <code>pageTracker</code>. We then replace all the instances of pageTracker (except where it is defined in the google analytics code block they provide you). You’ll find this located near the bottom of our <code>application.html.erb</code> file.</p>
<div class="typocode"><pre><code class="typocode_ruby "><span class="punct"><%</span> <span class="keyword">if</span> <span class="constant">RAILS_ENV</span> <span class="punct">==</span> <span class="punct">'</span><span class="string">production</span><span class="punct">'</span> <span class="punct">-%></span><span class="string">
<!--// Google Analytics //--</span><span class="punct">></span>
<span class="punct"><</span><span class="ident">script</span> <span class="ident">type</span><span class="punct">="</span><span class="string">text/javascript</span><span class="punct">"></span>
<span class="ident">var</span> <span class="ident">gaJsHost</span> <span class="punct">=</span> <span class="punct">(("</span><span class="string">https:</span><span class="punct">"</span> <span class="punct">==</span> <span class="ident">document</span><span class="punct">.</span><span class="ident">location</span><span class="punct">.</span><span class="ident">protocol</span><span class="punct">)</span> <span class="punct">?</span> <span class="punct">"</span><span class="string">https://ssl.</span><span class="punct">"</span> <span class="punct">:</span> <span class="punct">"</span><span class="string">http://www.</span><span class="punct">");</span>
<span class="ident">document</span><span class="punct">.</span><span class="ident">write</span><span class="punct">(</span><span class="ident">unescape</span><span class="punct">("</span><span class="string">%3Cscript src='</span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">gaJsHost</span> <span class="punct">+</span> <span class="punct">"</span><span class="string">google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E</span><span class="punct">"));</span>
<span class="punct"></</span><span class="regex">script>
<script type="text</span><span class="punct">/</span><span class="ident">javascript</span><span class="punct">"</span><span class="string">>
var pageTracker = _gat._getTracker(</span><span class="punct">"</span><span class="constant">UA</span><span class="punct">-</span><span class="constant">XXXXXX</span><span class="punct">-</span><span class="number">1</span><span class="punct">"</span><span class="string">);
pageTracker._trackPageview();
</script>
<% end -%>
<script type=</span><span class="punct">"</span><span class="ident">text</span><span class="punct">/</span><span class="ident">javascript</span><span class="punct">"</span><span class="string">>
var _gap = new GoogleAnalyticsProxy();
</script></span></code></pre></div>
<p>We now have <code>_gap</code> available throughout our project and can call <code>_trackEvent()</code> and <code>_trackPageview()</code> with it. Note: You can use any JS variable name that you want, _gap is just what I went with.</p>
<h2>Get GoogleAnalyticsProxy</h2>
<p>I’ve gone ahead and tossed this small JavaScript class (known as <a href="http://github.com/robbyrussell/GoogleAnalyticsProxy">GoogleAnalyticsProxy</a>) on Github for your enjoyment. I have some more articles in the works that will show you some tips for how to make the most of Google Analytics. If you have any questions and/or ideas for related article topics, don’t hesitate to let me know.</p>
<p id="fn1"><sup>1</sup> <a href="http://www.robbyonrails.com/articles/2009/10/21/tracking-ajax-driven-events-in-ruby-on-rails-for-google-analytics-conversion-goals">Tracking <span class="caps">AJAX</span>-driven events in Ruby on Rails for Google Analytics conversion goals</a></p><p>As mentioned in a recent article<sup><a href="#fn1">1</a></sup>, I’ve been diving deep into <a href="http://www.google.com/analytics/">Google Analytics</a> lately while working on a few client projects. We’re aiming to use much more of the features of Google Analytics and have been hitting some roadblocks with the development versus production application environments. Once you begin to dive into event tracking and <span class="caps">AJAX</span>-driven goal conversions, relying on just the sample code that Google Analytics provides you is going to result in you looking at a handful of JavaScript errors.</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfu1f/pagetracker-is-not-defined"><img src="http://img.skitch.com/20091101-c62euttfs5ejejt2eqpfxpnfau.preview.jpg" alt="pageTracker is not defined" /></a></div>
<p>another example from the firebug javascript console…</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfu1g/firebug-pagetracker-is-not-defined"><img src="http://img.skitch.com/20091101-p5mb21ufih99n3sa6uafsc4gyf.preview.jpg" alt="firebug pageTracker is not defined" /></a></div>
<p>We see JavaScript errors like this because we don’t load the google analytics code in our development environments. As you can see, we are only loading this in our production environment.</p>
<div class="typocode"><pre><code class="typocode_ruby "> <span class="punct"><%</span> <span class="keyword">if</span> <span class="constant">RAILS_ENV</span> <span class="punct">==</span> <span class="punct">'</span><span class="string">production</span><span class="punct">'</span> <span class="punct">-%></span><span class="string">
<!--// Google Analytics //--</span><span class="punct">></span>
<span class="punct"><</span><span class="ident">script</span> <span class="ident">type</span><span class="punct">="</span><span class="string">text/javascript</span><span class="punct">"></span>
<span class="ident">var</span> <span class="ident">gaJsHost</span> <span class="punct">=</span> <span class="punct">(("</span><span class="string">https:</span><span class="punct">"</span> <span class="punct">==</span> <span class="ident">document</span><span class="punct">.</span><span class="ident">location</span><span class="punct">.</span><span class="ident">protocol</span><span class="punct">)</span> <span class="punct">?</span> <span class="punct">"</span><span class="string">https://ssl.</span><span class="punct">"</span> <span class="punct">:</span> <span class="punct">"</span><span class="string">http://www.</span><span class="punct">");</span>
<span class="ident">document</span><span class="punct">.</span><span class="ident">write</span><span class="punct">(</span><span class="ident">unescape</span><span class="punct">("</span><span class="string">%3Cscript src='</span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">gaJsHost</span> <span class="punct">+</span> <span class="punct">"</span><span class="string">google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E</span><span class="punct">"));</span>
<span class="punct"></</span><span class="regex">script>
<script type="text</span><span class="punct">/</span><span class="ident">javascript</span><span class="punct">"</span><span class="string">>
var pageTracker = _gat._getTracker(</span><span class="punct">"</span><span class="constant">UA</span><span class="punct">-</span><span class="constant">XXXXXX</span><span class="punct">-</span><span class="number">1</span><span class="punct">"</span><span class="string">);
pageTracker._trackPageview();
</script>
<% end -%></span></code></pre></div>
<p>To <a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiEventTracking.html#_gat.GA_EventTracker_._trackEvent">track an event with Google Analytics</a>, you’d need to trigger something like:</p>
<div class="typocode"><pre><code class="typocode_ruby "> <span class="ident">pageTracker</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Button</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Click</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Get in touch</span><span class="punct">');</span></code></pre></div>
<p>As you can see from our code earlier, in development, the <code>pageTracker</code> variable isn’t defined and that’s why we’re getting those JS errors. We also don’t want to add conditionals everywhere in our application to check if we’re in development or production environment.. as that’d just make our views uglier than they need to be. So, I decided that I’d create a proxy class in JavaScript that would allow us to trigger <code>_trackEvent()</code> and <code>_trackPageview()</code> and handle it appropriately.</p>
<p>This class works with the following logic:</p>
<ul>
<li>if google analytics <strong>is</strong> loaded, pass the parameters to the real <code>pageTracker</code></li>
<li>if google analytics <strong>is <span class="caps">NOT</span></strong> loaded, output the information to <code>console.log()</code> for debugging purposes</li>
</ul>
<p>For example, on a gallery on our web site… we track when people navigate next and/or previous through the photos. In our development environment, I can watch the JavaScript console output the following:</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfu19/firebug-gap"><img src="http://img.skitch.com/20091101-jwbyprqyaj68hxtjw8bbg6mccm.preview.jpg" alt="Firebug - GAP" /></a></div>
<p>And in our production environment, we can see that this was sent to Google Analytics.</p>
<div class="thumbnail"><a href="http://skitch.com/robbyrussell/nfuut/firebug-trackevent"><img src="http://img.skitch.com/20091101-q9dkn8tw3kyndxr55fqed6k8fq.preview.jpg" alt="Firebug - trackEvent()" /></a></div>
<p>We’re able to do this by initializing the GoogleAnalyticsProxy class and calling these functions through it. For example:</p>
<div class="typocode"><pre><code class="typocode_ruby "> <span class="ident">_gap</span> <span class="punct">=</span> <span class="ident">new</span> <span class="constant">GoogleAnalyticsProxy</span><span class="punct">();</span>
<span class="ident">_gap</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Video</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Play</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Homepage video</span><span class="punct">');</span>
<span class="ident">_gap</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Video</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Pause</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Homepage video</span><span class="punct">');</span>
<span class="ident">_gap</span><span class="punct">.</span><span class="ident">_trackEvent</span><span class="punct">('</span><span class="string">Button</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Click</span><span class="punct">',</span> <span class="punct">'</span><span class="string">Call to action X</span><span class="punct">');</span></code></pre></div>
<p>You’ll see that we’re just calling <code>_gap</code> versus <code>pageTracker</code>. We then replace all the instances of pageTracker (except where it is defined in the google analytics code block they provide you). You’ll find this located near the bottom of our <code>application.html.erb</code> file.</p>
<div class="typocode"><pre><code class="typocode_ruby "><span class="punct"><%</span> <span class="keyword">if</span> <span class="constant">RAILS_ENV</span> <span class="punct">==</span> <span class="punct">'</span><span class="string">production</span><span class="punct">'</span> <span class="punct">-%></span><span class="string">
<!--// Google Analytics //--</span><span class="punct">></span>
<span class="punct"><</span><span class="ident">script</span> <span class="ident">type</span><span class="punct">="</span><span class="string">text/javascript</span><span class="punct">"></span>
<span class="ident">var</span> <span class="ident">gaJsHost</span> <span class="punct">=</span> <span class="punct">(("</span><span class="string">https:</span><span class="punct">"</span> <span class="punct">==</span> <span class="ident">document</span><span class="punct">.</span><span class="ident">location</span><span class="punct">.</span><span class="ident">protocol</span><span class="punct">)</span> <span class="punct">?</span> <span class="punct">"</span><span class="string">https://ssl.</span><span class="punct">"</span> <span class="punct">:</span> <span class="punct">"</span><span class="string">http://www.</span><span class="punct">");</span>
<span class="ident">document</span><span class="punct">.</span><span class="ident">write</span><span class="punct">(</span><span class="ident">unescape</span><span class="punct">("</span><span class="string">%3Cscript src='</span><span class="punct">"</span> <span class="punct">+</span> <span class="ident">gaJsHost</span> <span class="punct">+</span> <span class="punct">"</span><span class="string">google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E</span><span class="punct">"));</span>
<span class="punct"></</span><span class="regex">script>
<script type="text</span><span class="punct">/</span><span class="ident">javascript</span><span class="punct">"</span><span class="string">>
var pageTracker = _gat._getTracker(</span><span class="punct">"</span><span class="constant">UA</span><span class="punct">-</span><span class="constant">XXXXXX</span><span class="punct">-</span><span class="number">1</span><span class="punct">"</span><span class="string">);
pageTracker._trackPageview();
</script>
<% end -%>
<script type=</span><span class="punct">"</span><span class="ident">text</span><span class="punct">/</span><span class="ident">javascript</span><span class="punct">"</span><span class="string">>
var _gap = new GoogleAnalyticsProxy();
</script></span></code></pre></div>
<p>We now have <code>_gap</code> available throughout our project and can call <code>_trackEvent()</code> and <code>_trackPageview()</code> with it. Note: You can use any JS variable name that you want, _gap is just what I went with.</p>
<h2>Get GoogleAnalyticsProxy</h2>
<p>I’ve gone ahead and tossed this small JavaScript class (known as <a href="http://github.com/robbyrussell/GoogleAnalyticsProxy">GoogleAnalyticsProxy</a>) on Github for your enjoyment. I have some more articles in the works that will show you some tips for how to make the most of Google Analytics. If you have any questions and/or ideas for related article topics, don’t hesitate to let me know.</p>
<p id="fn1"><sup>1</sup> <a href="http://www.robbyonrails.com/articles/2009/10/21/tracking-ajax-driven-events-in-ruby-on-rails-for-google-analytics-conversion-goals">Tracking <span class="caps">AJAX</span>-driven events in Ruby on Rails for Google Analytics conversion goals</a></p>
Justin Gallagherurn:uuid:74c87ae9-11a7-4343-8250-31ca1701e73c2010-01-03T17:11:32-05:002010-02-06T07:57:32-05:00Comment on Tracking Google Analytics events in development environment with GoogleAnalyticsProxy by Justin Gallagher<p>Robby,</p>
<p>Thanks for this, it was almost exactly what I was looking for to track events in production and log events in development. I’ve been using jQuery in my Rails apps lately, and have <a href="http://github.com/justing/GoogleAnalyticsProxy" rel="nofollow">forked your project on github</a> and modified the code slightly to work without the Prototype framework. I’ve included the link above in case you or anyone else is interested.</p>
<p>Thanks again.</p>
<p>-Justin</p>