Cant get google analytics working on rails project - ruby-on-rails

Currently I'm using rails 5 and have been looking for a method of implementing google analytics in my application with turbolinks. Every site I go to says something different, and I've gone through loads of SO questions and none of them seem to work or are outdated.
Here's a shorter list of the methods I've tried:
https://medium.com/weareevermore/how-to-add-google-analytics-tracking-that-works-with-turbolinks-c5023610846d
http://nithinbekal.com/posts/turbolinks-google-analytics/
Rails 4 turbolinks with Google Analytics
http://railsapps.github.io/rails-google-analytics.html
I really thought that last one was gonna be most promising ¯\_(ツ)_/¯
So my question is what is the most updated method of integrating google analytics into a rails application?

I ran into an issue before with Rails 5 and Turbolinks and came across this issue for help.
It looks like you have things working with rack-tracker (based on ekremkaraca's comment). If you don't want to use a dependency you can set up Google Analytics with fairly minimal code using a partial and javascript snippet. I have a few apps configured this way:
app/assets/javascripts/google_analytics.js
document.addEventListener('turbolinks:load', function(event) {
if (typeof ga === 'function') {
ga('set', 'location', event.data.url);
ga('send', 'pageview');
}
});
app/views/layouts/_ga.html.haml (Using haml and not erb in this example)
:javascript
(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', 'YOUR_GA_CODE_HERE');
app/views/layouts/application.html.haml (Include the _ga partial in the head)
!!!
%html
%head
= stylesheet_link_tag 'application', media: 'all'
= javascript_include_tag 'application'
= render 'layouts/ga'
%body
= yield
app/assets/javascripts/application.js
...
//= require google_analytics

Related

AngularJS with Google Analytics

I want to add Google Analytics code to my AngularJS app.
I am using Ruby On Rails as a backend framework. The AngularJS application.html.erb file of Rails loads only on the first request.
So, I am putting google analytics code inside viewcontentLoad event.
$rootScope.$on('$viewContentLoaded', function () {
(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-XXXX-Y', 'auto');
// ga('send', 'pageview');
ga('send', 'pageview', {'page': $location.path()});
});
I don't know if this is a valid way of inserting Google Analytics code or not.
This answer on Tracking Google Analytics Page Views with Angular.js may be helpful.
One of the comments suggests that this is a good way to do it:
$rootScope.$on('$routeChangeSuccess', ...)

Rails 4 turbolinks with Google Analytics

I'm wondering what is the best way to implement Google Analytics tracking code along with the turbo linking in Rails 4. Will the normal snippet work? I've also seen a gems for this but I'm not sure what it does.
I like vladCovaliov's solution because it seems most new accounts use Universal Analytics by default (which is also better featured in my opinion). However, I think this answer needs to be combined with the other suggestions that comment out the initial pageview, use the page:change event, and track pageviews, not events.
For example, in your <head>:
<% if Rails.env.production? %>
<script>
(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-XXXXXXXX-X', 'auto');
//ga('send', 'pageview');
</script>
<% else %>
<script>
function ga () {
var params = Array.prototype.slice.call(arguments, ga.length);
console.log("GoogleAnalytics: " + params);
};
</script>
<% end %>
And then in a js file you have loaded through the asset pipeline:
$(document).on('page:change', function() {
ga('send', 'pageview', window.location.pathname);
});
This will record a pageview for each page you load with or without Turbolinks. Note that the window.location.pathname is required, otherwise you can get the URL of the first page loaded for all the subsequent page loads. (This also gives you a nice place to edit the URL reported if you wanted to, say, strip out :id path segments from RESTful URLs.)
You can also then easily call:
ga('send', "event", category, action, label, count);
To report Events for other interesting javascript events in your site.
I've went with a different approach that I saw on some web site but it seems reasonable.
Add GA to your header like usual but with a small modification of commenting out the trackPageview event from happening automatically.
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-FOOBAR']);
//_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
Then add this somewhere in your body because the body gets reloaded for turbolinks.
<% if Rails.env.production? %>
<script>_gaq.push(['_trackPageview']);</script>
<% end %>
The production check is optional but this is a nice way to not have GA track localhost hits if you're actively developing. The other perk is you don't have to worry about messing with page:change or page:load bindings and that you can be confident that it'll work on any browser that's trackable by GA without having to worry about double hits or anything weird.
I think a better idea is to use the new Universal Analytics (from analytics.js file).
Universal Analytics Solution
(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', "#{GA_UA}", "#{GA_URL}");
ga('send', 'pageview');
And then when you wanna send an event for example, you can use
<script> ga('send', "event", "#{category}", "#{action}", "#{label}", "#{count}"); </script>
Be careful to render this code in the body, and not in the head. Turbo-links only replaces the body.
And also be careful:
1) The GA_URL needs to match your pages's url
2) The Events show up in real time, but in the events tab, they only appear after 24h +
3) Your account's property need to be 'Universal' for this solution to work
Universal Analytics docs:
https://support.google.com/analytics/answer/2790010?hl=en&ref_topic=2790009
A quick glance into the source shows, that the only thing this gem does is to add some javascript to the asset-pipeline
# google-analytics-turbolinks/lib/assets/javascripts/google-analytics-turbolinks.js.coffee
if window.history?.pushState and window.history.replaceState
document.addEventListener 'page:change', (event) =>
# Google Analytics
if window.ga != undefined
ga('set', 'location', location.href.split('#')[0])
ga('send', 'pageview')
else if window._gaq != undefined
_gaq.push(['_trackPageview'])
else if window.pageTracker != undefined
pageTracker._trackPageview();
That's all there is to it. You can either use the gem or add something like this code-snippet manually to your javascript-assets.
I appreciate scottwb's answer, but unfortunately it does not work with Rails 5. In Rails 5 Turbolinks events were renamed. The 'page:change' event was renamed to 'turbolinks:load'. This is why his example does not work anymore.
You can find an overview of how they were renamed here: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee
Since this took me some time to figure out, I am posting the proper Rails 5 implementation for everybody coming after me.
Put the following code in your <head>
<script>
(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-XXXXXXXX-X', 'auto');
//ga('send', 'pageview'); //moved to an asset file because of turbolinks
</script>
And then in a js file (eg. application.js) in you asset pipeline:
$(document).on('turbolinks:load', function() {
ga('send', 'pageview', window.location.pathname + window.location.search);
});
Remember to replace "UA-XXXXXXXX-X" with your Google Analytics ID.
This solution has worked the best for me: http://reed.github.io/turbolinks-compatibility/google_analytics.html.
It requires at least Turbolinks v2.1.0 or greater.
We just took the standard snippet provided by Google, translated it to CoffeeScript, then modified the last action so it is bound to both the "ready" and "page:load" events. We also added conditional statement to only send the data if the current visitor is not at an admin (so our data remains as clean as possible).
((i, s, o, g, r, a, m) ->
i["GoogleAnalyticsObject"] = r
i[r] = i[r] or ->
(i[r].q = i[r].q or []).push arguments
return
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
return
) window, document, "script", "//www.google-analytics.com/analytics.js", "ga"
ga "create", 'UA-XXXXXXXX-XX', "yourdomain.com"
$(document).on 'ready page:load', ->
ga "send", "pageview", window.location.pathname unless $('body').data('admin') is true
According to this site, you only need to do a slight modification. The problem with Turbolinks is that it only updates parts of the website and therefore, Google Analytics often doesn't perceive that the page has changed. Thus, you must notify it manually by adding the following CoffeeScript to a file in your assets/javascript folder:
$(document).on 'page:change', ->
if window._gaq?
_gaq.push ['_trackPageview']
else if window.pageTracker?
pageTracker._trackPageview()
NOTE: this is not my code, it is taken directly from the previously linked website

Google Adwords not Tracking Conversions

In my Rails app that uses the Devise gem, it redirects back to the root which has this code:
<script>
(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-40000000-1', 'foo.com');
ga('send', 'pageview');
_gaq.push(['_trackPageview', '/home/articles/user_sign_up']);
</script>
In Google Analytics I have Destination set to:
Equals to /home/articles/user_sign_up
However, it's not registering as a conversion. Can someone please help me figure out what I did wrong?
The URL of the page that the code appears on is /home/articles so my intent was to try to overwrite what Google thought the URL was using:
_gaq.push(['_trackPageview', '/home/articles/user_sign_up']);
I think your are mixing up the new analytics.js syntax with the traditional ga.js one.
Try using
ga('send', 'pageview', '/home/articles/user_sign_up');
See the relevant documentation.

Rails with pjax, pjax:complete event is raised, but full page loads regardless

I am trying to use pjax with my Rails app.I am not using a gemified version of pjax (i.e. I downloaded the plain JS version). I get the alert messages but the entire page still reloads.
My layout page looks like this:
doctype 5
html
head
title Cassandra
= stylesheet_link_tag 'application', media: 'all'
= javascript_include_tag 'application'
= csrf_meta_tags
body
= render('layouts/navbar')
div#content.row
div#pjax-container.large-12.columns
= render('layouts/breadcrumbs')
= render('layouts/flash')
= yield
= render('layouts/footer')
My js looks like this (inside a doc.ready)
$(document).pjax('a', '#pjax-container');
$(document).on('pjax:send', function() {
alert('pjax start');
})
$(document).on('pjax:complete', function() {
alert('pjax comp');
})
I get no console errors in Chrome and I will know for sure when it works because right now I
have not modified any server responses to not include the layout page, and the layout page will need to be tweaked etc, but right now I just want to get the scaffolding working

Facebook login in a Ruby on Rails application

I'm developing a Ruby on Rails application using the Facebook flogin button with JavaScript.
My code:*
<fb:login-button perms="email" onlogin="createFbSession();"></fb:login-button>
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js">
</script>
<script>
FB.init({
appId:"xxxxxxx", cookie:true,
status:true, xfbml:true
});
function createFbSession() {
FB.getLoginStatus(function(response) {
if (response.session) {
window.location = "<%= fb_login_path %>";
}
});
}
</script>
When I click on the flogin button, sometimes I receive the following error in the popup window:
An error occurred. Please try again later.
What does it mean?
You could use omniauth which lets you use facebook/twitter/openid etc... in ruby without having to use a js library linked in from facebook.
Railscasts have a great episode on a simple onmiauth setup which is well worth a watch and because omniauth returns similar data for all providers just change twitter to facebook and you should be fine.
Omniauth also allows for multiple providers in the same login system, as some people (myself included) prefer to use twitter so enforced facebook login would put me off.
When using the fb:login-button, for some reason, if you don't create it using the content_tag helper it breaks when rendered as html. In rails seems to work when rendered like this: <%= content_tag("fb:login-button", "Log in", {:scope=>"email"}) %>
Note: I'm using rails 3.1, I haven't tried that solution with previous versions.

Resources