46

The chrome extension guide has a tutorial for the old analytics install: https://developer.chrome.com/extensions/tut_analytics.html

The instructions just say to link to the https version and update the manifest to allow loading scripts from that URL. So those should still apply to the new version. And in fact I can see the script loading from the server.

Once the script loads analytics does not properly initialize it self and never processes it's internal queue (ga.f) to send those events to the server. There is no error in the console. It's just quietly does nothing.

My guess is that the new Universal Analytics is just not set up to run in the the extension environment but the universal docs make no mention of that: https://developers.google.com/analytics/devguides/collection/analyticsjs/

does anyone know if it's even possible to add Universal Analytics to an extension yet and when that might be added?

StefanHayden
  • 3,569
  • 1
  • 31
  • 38
  • I would imagine it would be replacing ga.js to analytics.js and changing the event/page tracking functionality from _gaq.push(... to ga('send'.. – vly Apr 21 '13 at 23:31
  • 2
    I imagined the same thing. But we were both in for a surprise. – StefanHayden Aug 03 '13 at 00:48
  • I founded this script on github, it work very well. https://github.com/melalj/universal-ga-extension – Giangimgs Apr 30 '18 at 11:27

6 Answers6

40

There's an issue for that on Google code: The solution is to pass analytics your own protocol check function or simply null for no checking, in an official way.

This has to come after ga('create', ...) :

ga('set', 'checkProtocolTask', null); // Disable file protocol checking.

So you don't need to modify the original analytics.js script. Just include the standard tracking code snippet (dont' forget to add the "https:" prefix) and add "https://www.google-analytics.com" to your Content Security Policy.

A note to ayal gelles' solution: It is not necessary to add chrome-extension://... to the Content Security Policy since it's already included in the 'self' statement. Also, instead of loading the script via hardcoded URL you should use chrome.runtime.getURL("path/to/analytics.js"). This way you don't need to know your extension's ID, Chrome will fill it in for you.

Sven Ackermann
  • 442
  • 5
  • 11
  • Hello, can you give a few more information on this? I tried adding the `checkProtocolTask` thing but it doesn't change anything. GA still doesn't seem to report anything - at least live view stays empty. – patchrail Mar 12 '14 at 15:53
  • 2
    I only took that answer from the linked issue. It works fine for me. Chrome developer tools show requests going to "http://www.google-analytics.com/collect" and in my GA realtime view I could see the values coming in. Here's a bit more code (you could also look at the changed code of my extension: http://goo.gl/jpmci6): `ga('create', 'UA-41499181-1', 'auto'); ga('set', 'checkProtocolTask', function(){}); ga('send', 'pageview');` – Sven Ackermann Mar 17 '14 at 11:09
  • Note that this doesn't work from content scripts! see here if that's what you need: http://stackoverflow.com/questions/10285886/chrome-extension-adding-external-javascript-to-current-pages-html – MasterScrat Jun 04 '14 at 09:05
  • Not working for me. Really frustrating how Google can't even make their own products work together correctly – Matt Vukas Oct 03 '14 at 04:11
  • 1
    You can also use `null` instead of `function(){}`. The `null` solution is documented here: https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks and both solutions are mentioned here: https://code.google.com/p/analytics-issues/issues/detail?id=312 – Roland Pihlakas Dec 26 '14 at 13:55
  • Also calling `chrome.extension.getURL` is unnecessary in case the analytics is located on background page. Local paths always point to extension's folder. – Roland Pihlakas Dec 26 '14 at 14:13
  • This is probably common knowledge, but it just stung me, make sure the ga('set'... is after ga('create'.... – SethWhite Nov 24 '15 at 18:24
  • Is there also a similar solution for the new gtag.js that Google is eagerly promoting? – kano May 07 '20 at 13:54
32

I wrote up a blog post on this - How to add Google’s Universal Analytics tracking to a Chrome extension

Here's the guts of it:

// Standard Google Universal Analytics code
(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','https://www.google-analytics.com/analytics.js','ga'); // Note: https protocol here

ga('create', 'UA-XXXXX-YY', 'auto');
ga('set', 'checkProtocolTask', function(){}); 
ga('send', 'pageview', '/options.html');

There are 3 points I’d particularly like to highlight:

  • Specify “https” at the start of the script address to match with the listing in the manifest.json file
  • Override checkProtocolTask with an empty function
  • Send a virtual pageview by specifying the path – /options.html – otherwise Google Analytics will reject a URL in the format chrome-extension://gdocgfhmbfbbbmhnhmmejncjdcbjkhfc/options.html
dvdsmpsn
  • 2,839
  • 1
  • 26
  • 40
  • I tried a basic extension that just opens popup.html with popup.js (like option) with no luck. – Josh Usre Aug 03 '15 at 19:49
  • 2
    just wanted to confirm that this solution still works for Chrome Extensions, too bad the Chrome team haven't updated the docs in years. https://developer.chrome.com/extensions/tut_analytics – lasec0203 May 20 '18 at 02:18
  • 2
    This is definitely the way to go. You might also want to use your own clientId (or userid) and store it in chrome.storage instead of using a cookie: ``` ga('set', 'cliendId': {cid from chrome.storage.sync}); ga(function (tracker) { chrome.storage.sync.set({ 'cid': tracker.get('clientId') }); }); ``` – SHamel May 01 '19 at 13:35
  • 2
    June, 2019 -- The solution above still works. But the `ga('require', 'displayfeatures');` is not required. – Denis L Jun 04 '19 at 10:55
9

I just encountered this and seem to have hacked my way through. This might break at some point or not be fully functional, but here goes:

  • Download the GA uglified+minified source code from here: https://www.google-analytics.com/analytics.js, put in your chrome extension folder, where it could be later loaded by the background page.

  • In it, find a function that looks something like this:

function Oa(){var a=M[B][E];if("http:"!=a&&"https:"!=a)throw"abort";}. 

This is the "point of failure" since our "protocol" is "chrome-extension:" and not either of the two.

  • So.. change this function to be something like:
function Oa(){var a=M[B][E];if("chrome-extension:"!=a&&"http:"!=a&&"https:"!=a)throw"abort";}
  • add a "Content Security Policy" of this sort to your manifest file, make sure it points to YOUR LOCAL version of analytics.js you have just modified:
"content_security_policy": "script-src 'self'  chrome-extension://EXTENSIONID/path/to/analytics.js;  object-src 'self'",
  • Change the GA snippet to ALSO point to that same file, something like this:
(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','chrome-extension://EXTENSIONID/path/to/analytics.js','ga');

hope this helps.

Touki
  • 7,465
  • 3
  • 41
  • 63
ayal gelles
  • 2,829
  • 1
  • 21
  • 18
  • 3
    Awesome solution until Google comes to realize their very own Chrome Extension don't support their *new* Analytics product. I mean, how silly can you be? ;-) – Gilad Peleg Sep 05 '13 at 07:48
  • 1
    Amazing thank you. The only problem is testing as the ID isn't known yet... but that can also be hacked around and google will fix it eventually. – Edz Dec 01 '13 at 21:35
2

I managed to get Google Analytics up and running using Chrome Platform Analytics (CPA). The only confusing part is how to set up a property in the administration console of GA. I had to create a Mobile Application property, which is not too intuitive.

Also, I created an options page that lets users disable analytics if desired, to comply with the opt-out requirements.

I hope that helps!

argenkiwi
  • 2,134
  • 1
  • 23
  • 26
2

Regarding new analytics.js (as opposite to old ga.js) this example works for me:

function setupGoogleAnalytics() {
  if (!window.ga) {
    (function(){
      window.ga = function() {
        (window.ga.q = window.ga.q || []).push(arguments);
      }, window.ga.l = 1 * new Date();
      var tag = 'script';
      var a = document.createElement(tag);
      var m = document.getElementsByTagName(tag)[0];
      a.async = 1;
      a.src = 'https://www.google-analytics.com/analytics.js';
      m.parentNode.insertBefore(a, m);
    })();
    ga('create', 'UA-XXXXXXX-Y', 'auto');
    ga('set', 'checkProtocolTask', null);
  }
}

Please note that you need to add following content_security_policy snippet to the manifest.json:

{
...
  "content_security_policy": "script-src 'self' https://www.google-analytics.com; object-src 'self'"
...
}
1

There's a way to use the Measurement Protocol to communicate with Google Analytics. I have developed a script for that :

https://github.com/melalj/universal-ga-extension

Simo
  • 464
  • 3
  • 16