16

In order to add google analytics to a chrome extension the official docs provide the following snippet:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXXX-X']);
_gaq.push(['_trackPageview']);

(function() {   var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;   ga.src = 'https://ssl.google-analytics.com/ga.js';   var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();

But google also recommends to migrate from ga.js to analytics.js.

ga.js is a legacy library. If you are starting a new implementation, we recommend you use the latest version of this library, analytics.js. For existing implementations, learn how to migrate from ga.js to analytics.js.

After following carefully the migration guide and upgrading the content security policy with the new script ( from https://ssl.google-analytics.com/ga.js to https://www.google-analytics.com/analytics.js ), it simply didn't work, without showing any error message.

Any suggestion welcome,

locropulenton
  • 4,743
  • 3
  • 32
  • 57
  • See the Google Analytics documentation for adding the script tag and sending custom events, https://developers.google.com/analytics/devguides/collection/analyticsjs/ Also make sure that you have added the UA-ID in your chrome extension webmaster page. – holmberd Feb 02 '18 at 16:22
  • https://stackoverflow.com/a/31654055/908121 – Ben Wilson May 25 '20 at 19:00
  • this is the [official documentation](https://developer.chrome.com/docs/extensions/mv3/tut_analytics/) from google themselves for this. – Gangula Aug 05 '23 at 17:46

6 Answers6

8

My solution is based on the official docs: https://developers.google.com/analytics/devguides/collection/analyticsjs/tracking-snippet-reference

But slightly modified:

(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');

ga('create', 'UA-XXXXX-Y', 'auto');

// Modifications: 
ga('set', 'checkProtocolTask', null); // Disables file protocol checking.
ga('send', 'pageview', '/popup'); // Set page, avoiding rejection due to chrome-extension protocol 
Denis L
  • 3,209
  • 1
  • 25
  • 37
  • 1
    @locropulenton you should definitely accept this answer. The last two lines really did the trick (`checkProtocolTask` and forcing a page path when sending `pageview`). – Lucio Paiva Feb 28 '20 at 00:58
  • Somehow this doesn't work for me. I got the following error: ```Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' https://www.googletagmanager.com". Either the 'unsafe-inline' keyword, a hash ('sha256-xxx'), or a nonce ('nonce-...') is required to enable inline execution. Refused to load the script 'https://www.google-analytics.com/analytics.js' because it violates the following Content Security Policy directive: "script-src 'self' https://www.googletagmanager.com". ``` – lzl124631x Aug 31 '20 at 09:46
  • @lzl124631x You need to configure also `content_security_policy ` in your manifest – Denis L Aug 31 '20 at 14:03
  • 1
    Unfortunately, Google Analytics v4 (GA4) does not support setting `checkProtocolTask` yet. More info - https://issuetracker.google.com/issues/174954288 – Raj Dec 28 '22 at 05:38
4

This will work great for those of you using react: https://github.com/lxieyang/chrome-extension-boilerplate-react

// manifest.json

"content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'"

// AnalyticsProvider.jsx

import { useEffect } from 'react';

export default function AnalyticsProvider() {
  const initAnalytics = () => {
    setTimeout(() => {
      const gaPlugin = _gaq || [];
      gaPlugin.push(['_setAccount', 'XX-XXXXXXXXXX-X']);
      gaPlugin.push(['_trackPageview']);
    }, 2000);
  };

  useEffect(() => {
    (function() {
      var ga = document.createElement('script');
      ga.type = 'text/javascript';
      ga.async = true;
      ga.src = 'https://ssl.google-analytics.com/ga.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(ga, s);
      initAnalytics();
    })();
  }, []);

  return null;
}

// Popup.jsx (or any other page you choose)

import AnalyticsProvider from './AnalyticsProvider';

...

return (
    <div className={classes.root}>
    ...
      <AnalyticsProvider />
    ...
    </div>
  );
  • 4
    Please consider adding some explanation and details to your answer. While it might answer the question, just adding some code does not help OP or future community members understand the issue or solution. – hongsy Jan 22 '20 at 08:38
  • FYI, this was throwing a `Uncaught ReferenceError: _gaq is not defined` in my console. I added a `var _gaq = _gaq || [];` just before the `const gaPlugin` cand that seemed to clear it. – Doug Jan 21 '22 at 00:47
2

Did you make sure to put the analytics script into a separate javascript file?

Google Chrome extensions won't execute inline JS, see https://developer.chrome.com/extensions/contentSecurityPolicy#JSExecution

1

For using google analytics with mv3 the easiest way is to use measurement protocol. In short, it allows you to send event tracking to Google Analytics through a normal POST call.

Check this answer - https://stackoverflow.com/a/73825802/8719381

Sanuj Bansal
  • 89
  • 1
  • 8
-1

Try to use the following snippet for async tracking, here the docs

<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
F. Leone
  • 594
  • 3
  • 14
-1

[EDIT] As per the comments below, this solution does not work with Manifest V3.

The Chrome Extensions documentation has a tutorial explaining how to do this: developer.chrome.com/docs/extensions/mv3/tut_analytics.

Update your manifest:

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

Include JavaScript like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXXX-X']);
_gaq.push(['_trackPageview']);

(function() {
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  ga.src = 'https://ssl.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

Track events as usual:

function trackButton(e) {
  _gaq.push(['_trackEvent', e.target.id, 'clicked']);
};
Sam Dutton
  • 14,775
  • 6
  • 54
  • 64
  • 2
    This does not work. To begin with, the CSP format is wrong. in V3 it is an object as opposed to a string, as explained here: https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#content-security-policy – vandre Sep 09 '21 at 22:08
  • You're right — and unbundled scripts aren't allowed in Manifest V3: https://developer.chrome.com/docs/webstore/program_policies/#:~:text=Additional%20Requirements%20for%20Manifest%20V3. I've added a note to my answer. – Sam Dutton Sep 20 '21 at 18:51