Double Tracking in GA without Named Trackers – Part 3

The first part of this series introduced the problem – wanting to track to 2 different GA properties without double-coding the tracking calls – and the second part proposed a solution, using a GA plugin (get the code here) to amend GA’s sendHitTask to send a copy of the payload to an additional property.  This part explains one of the caveats of that idea and how to overcome it.

There are actually several caveats, most notably the one that this isn’t tested nearly enough to make it ready for production. Second, for reasons I haven’t yet looked into, this does not work with named trackers (which should be no real problem since this is designed to avoid named trackers in the first place) (actually that was me being stupid, I forgot the “require” needs to be prefixed with the tracker name as well). The third one–

Well, that’s actually closely connected to the problem this is presumed to solve. When create multiple trackers and send of hit on a per-tracker basis you have the chance to configure them differently. For example if you have custom dimensions that you want to send to one property, but not the other you can add them via a configuration object in your call to the original tracker while omitting them from the duplicate:

ga('send', {
hitType: 'pageview',
    dimension1: 'theSecretSauce',

This does not, by default, work with the dualtracking plugin since the same configuration is used for both trackers.

To mitigate this I have introduced an option to manipulate the payload via a configuration option for the plugin. It allows you to overwrite fields in the payload with arbitrary values; and if you set a field name to “null” the value will be ommitted completely in the secondary call.

The following example demonstrates a likely use case. Image you allow a third party to track your page via their own GA property  (personally I wouldn’t, but I have seen it happen with real life clients). Your own property has the user id feature enabled for cross-device tracking, however you’d rather not share this with the third party, so you’d unset it in to dualtracking plugin:

  ga('create', 'UA-883789-7', 'auto');

  ga('require', 'dualtracking', {
      property: 'UA-883789-8',
      debug: true,
      transport: 'image',
      fields: {
  ga('send', 'pageview');
<script async src=""></script>

The “fields” property in the configuration is the property that affect the payload. Notice that is uses the parameter names from the tracking url rather than human readable field names you’d use in your set calls; you can see which field name corresponds to which parameter via the GA field reference.

The plugin code breaks down to original tracker payload to key/value fields; the values are replaced with corresponding values from the “fields” object, or deleted completely when the corresponding value is null. Then the key/value pairs will be reassembled into a payload and dispatched to (or an other url you specify via the “endpoint” property in the plugin configuration, e.g. if you want to send a copy of the data to your own server. Keep in mind that XHR requests to arbitrary server might not work by default, so when in doubt choose “image” as transport method. Or don’t choose at all since image is the default).

You can see this when you look at the network console in your browser while calling up my test page (which might be broken from time to time, but I leave a status message when I’m currently fiddling with the code).

Finally a short overview on the configuration options:

  • property (string ) – The UAID for the secondary property
  • endpoint (string) – The URL the data is send to (defaults to “”;)
  • debug (bool) – prints status messages to the browser console
  • fields (object) – an optional JSON object with key/value pairs. Corresponding fields are overwritten in the payload or removed if the new vaue is null

Leave a Reply

Your email address will not be published. Required fields are marked *