What does the `cx` parameter do in Gtag implementations?

Viewed 83

I have been debugging an issue with Google Analytics 4 where when a GA4 property is connected to an existing GA3 gtag property, and the request to fetch the JavaScript from GTM contains the parameter cx=c, the resulting JavaScript does not contain the required child container for GA4.

Image of gtag with and without cx=c

https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXX-1&l=dataLayer&cx=c

The obvious fix is to remove the cx=c parameter and test, or to use another implementation of GA4 directly, but that is not the question.

After seeing the suggested implementation from Google, (e.g. no cx) and this version (with the cx) passed around in various online discussions, Github code and issues, etc. I am trying to figure out what it does. I have searched all Google docs, searched Github and Stack Overflow. I find it referenced with respect to Firebase, but nothing else. Does anyone know what this parameter does, officially?

1 Answers

Short answer: we have no clue what it does.

Longer answer: as you may know, GTM can deploy gtag. Since it can do that, it has the code for generating that function. Although that code is minified, it can still be useful:

var Fn = function (a, b, c) {
  if (!En() && !sg(a)) {
    var d = c ? "/gtag/js" : "/gtm.js", e = "?id=" + encodeURIComponent(a) + "&l=" + Cd.ba,
    f = 0 === a.indexOf("GTM-");
    f || (e += "&cx=c"); var g = Dn();
    g && (e += "&sign=" + Cd.Xd);
    var l = Bn(b, d + e);
    if (!l) {
      var m = Cd.uc + d; g && bb && f && (m = bb.replace(/^(?:https?:\/\/)?/i, "").split(/[?#]/)[0]);
      l = Ri("https://", "http://", m + e)
    } rg().container[a] = !0; hb(l)
  }
} 

See what it does? f indicates whether there is "GTM-" in a or not. And I didn't look up a, but a must be the fetch url. Now, f becomes a binary representation instead of the -1 returned by the indexOf.

Judging from this code, GTM deploys the cx parameter with a very hardcoded value whenever it deploys something that is not GTM, I imagine, from it's own family of fetch urls, which can include GTM itself. Why GTM doesn't want cx=c for its code? No idea. I have it loaded with it more often than without.

But here's another place where it's used:

Gn = function (a, b) {
    var c; if (c = !En()) c = !rg().destination.hasOwnProperty(a); if (c) {
      var d = "/gtag/destination?id=" + encodeURIComponent(a) + "&l=" + Cd.ba + "&cx=c";
      Dn() && (d += "&sign=" + Cd.Xd); var e = Bn(b, d); e || (e = Ri("https://", "http://", Cd.uc + d)); rg().destination[a] = !0; hb(e)
    }
  };

En() is always false. It looks like it's some weird remnants from GTM's dev environments. Poor env variables management on GTM's side, but no one cares.

I stopped looking into the Gn function at this point. But if you want to persist digging, you're free to do so. I have a sneaking suspicion that the cx parameter does exactly no difference on the side of the consumer (our side). It may be something beneficial for Google's dev team, but I doubt it. Params, hardcoded like this are rarely a good idea. Looks to me like a fluke.

Related