10

Is it possible to add google analytics into a chrome extension using manifest v3 ? How can i do that ?

I found this post from stackoverflow : Add Google Analytics to a Chrome Extension so i tried the code into the accepted answer, with

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

into my manifest.json, but when i load my extension i got this error : 'content_security_policy.extension_pages': Insecure CSP value "https://ssl.google-analytics.com" in directive 'script-src'.

I feel like it's not possible to use google analytics with chrome extension right now, but it's weird because into the chrome web store dashboard, we can see this field : https://i.stack.imgur.com/RVv59.jpg

Did i miss something ?

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
Gauthier T.
  • 556
  • 1
  • 4
  • 16
  • Are you trying to use GA in service_worker or content_script? – Kenny Lim Feb 05 '22 at 00:50
  • i'm on manifest v3 so it's a service_worker, manifest v3 doesn't allow content_script – Gauthier T. Feb 06 '22 at 15:56
  • 1
    MV3 doesn't allow background script but it supports content_script. – Kenny Lim Feb 08 '22 at 02:17
  • true, sorry i was confused between background_script and content_script. I have to use service_worker because my extension does not interract with the web page and it should work when chrome is in background. – Gauthier T. Feb 13 '22 at 15:25
  • Btw, the screenshot mentioned are for the Chrome web store only, meaning, it tracks how many times the extension is installed/uninstalled and what OSs and countries the users are from, but, that's it. It doesn't track events in the extension itself or in any other background/content-scripts, so, this field is for your extension's Chrome web store only. – user7607751 Apr 05 '22 at 02:44
  • 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

2 Answers2

7

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.

Here's the setup I used to track a click / other events:

The user clicks a button in the extension The content script/popup.html sends a message to the service worker (background.js) using Message Passing saying the event should be recorded. The service worker posts the event to Google Analytics using fetch() And here's some sample code that runs in the service worker:

const ANALYTICS_PATH = "https://www.google-analytics.com/collect";

async function postData(url = '', data = {}) {

  // Default options are marked with *
  const response = await fetch(url, {
    method: 'POST',
    mode: 'no-cors',
    cache: 'no-cache',
    credentials: 'same-origin',
    headers: {
       'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow',
    referrerPolicy: 'no-referrer',
    body: data
  });

}

var gaParams = new URLSearchParams();
gaParams.append("v", 1);
gaParams.append("tid", "UA-XXXX-X");
gaParams.append("cid", xxxxx);
gaParams.append("t", "event");
gaParams.append("ec", "myEventCategory");
gaParams.append("ea", "myEventAction");

postData(ANALYTICS_PATH, gaParams)

Note:- This api does not give response codes if something is wrong, instead of using https://www.google-analytics.com/mp/collect directly on prod, one should first try https://www.google-analytics.com/debug/mp/collect.

PS. I found this solution from a comment on this source:- https://www.indiehackers.com/post/how-to-add-google-analytics-with-manifest-v3-468f1750dc

Sanuj Bansal
  • 89
  • 1
  • 8
  • 1
    even then can switch over to new GA4 I guess ?https://developers.google.com/analytics/devguides/collection/protocol/ga4 – HaveAGuess Oct 05 '22 at 11:25
  • seems the debug/mp/collect need JSON, it doesn't accept URL params `{ "validationMessages": [ { "description": "Unable to parse Measurement Protocol JSON payload. invalid JSON in google.analytics.measurement.Measurement, near 1:1 (offset 0): unexpected character: 'v'; expected '{'", "validationCode": "VALUE_INVALID" } ] }` – Dee Jan 04 '23 at 14:31
  • @Sanuj i tried to send to mp/collect but it doesn't recognise countries, u know the param for country? – Dee Jan 07 '23 at 13:13
  • @Sanuj - How do you get the clientId (cid) ? – hybrid Jan 24 '23 at 03:22
  • 1
    @hybrid cid or client id should be a unique id to represent each user in your application. I use user id for my application as cid – Sanuj Bansal Jan 25 '23 at 08:29
  • cid can just be anything random, save it to localStorage to reuse; and about the params, i had to use json with GA4 mp/collect, not URIencoded values – Dee Jan 25 '23 at 09:38
  • Does it work with G-XXXXXXXX ? – Alexey Sh. Mar 24 '23 at 18:48
  • @AlexeySh. it works with G tag but json, not URLSearchParams – Dee Mar 28 '23 at 07:00
4

I used this way to add google analytics to override.html(chrome_url_overrides) or popup.html in manifest V3:

override.html:

<head>

  // 1- Download from 'https://ssl.google-analytics.com/ga.js' and use locally
  <script src="./ga.js"></script>

  // 2- Instead of use 'content_security_policy' property in 'manifest.json' add this:
  <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-eval' http://www.google-analytics.com https://example.com ;style-src 'self' 'unsafe-inline' http://www.google-analytics.com https://example.com; media-src *;img-src *">
  // or
  <meta http-equiv="Content-Security-Policy" content="default-src *;img-src * 'self' data: https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' *;style-src  'self' 'unsafe-inline' *">

</head>

3- Create analytics-override.js:

var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-01234567-89"]);
_gaq.push(["_trackPageview", "/override.html"]);

4- In override.js:

window.onload = function(){    
    const scriptTag = document.createElement("script");
    scriptTag.src = chrome.runtime.getURL("./analytics-override.js");
    scriptTag.type = "text/javascript";
    document.head.appendChild(scriptTag);
}

I hope it helps you.

Morteza Ebrahimi
  • 740
  • 1
  • 8
  • 20