Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

I am using Tealium for my Google Universal Analytics tagging, and need to retrieve the value of the GA-assigned "Client ID", and map that back to GA as a value in a custom dimension. I see several articles on how to do this in Google Tag Manager, such as this one https://www.simoahava.com/gtm-tips/use-customtask-access-tracker-values-google-tag-manager/ or this one https://optimizationup.com/expose-client-user-id-google-analytics/. I need to do essentially the same thing, but using Tealium. Can anyone recommend a way to accomplish this?

18 REPLIES 18

Get Google Analytics Client ID and map to a GA custom dimension

Tealium Employee

@Krasner

Here is a function I've used leveraging Google's built-in tracker.

Add this to a JavaScript extension scoped to All Tags.

ga(function() {
var trackers = ga.getAll();
for (var i = 0; i < trackers.length; ++i) {
var tracker = trackers[i];
var trackerName = tracker.get('name');

ga(function(trackerName) {
utag.data._ga = tracker.get('clientId');
});
}
});

 

Declare _ga as a UDO variable in the Data Layer tab.

Then map _ga to your custom dimension within the tag mappings.

Please let me know if this works for you.

Cheers,
-Dan

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

Thank you, @dan_george, for the detailed solution. I think I am quite close to getting this to work. I now see the value fo the GA Client ID showing up in the new UDO variable called "_ga" in the Tealium Web companion. However, even though I have mapped it in the Google Universal Analytics tag to the custom dimension, it does not appear to be getting populated. Perhaps there might be a timing issue? I have the extension set to "After Load Rules (default)". And I have the GUA tag set to Bundle=ON, Wait=OFF. Wondering if perhaps the way things are set up, the variable might not have the data by the time the tag references it? Any thoughts?

Get Google Analytics Client ID and map to a GA custom dimension

Tealium Employee

@Krasner

I would scope the extension to the GA tag as this will ensure the logic is ran in time and also when the GA lib is loaded.

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

Dan, again thanks. I thought the hard part would be getting the client ID value. Your solution readily solved that. For some reason, I have not been successful to map the value to the dimension in the Google Universal Analytics tag. I'll reach out to my CSM or to support to see if we can get it that last inch over the goal line, and will update here. Thanks for your help getting me this far.

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

Hi @dan_george. My CSM helped me determine that the code you provided works properly if I define the _ga variable as a "first party cookie", rather than as a "UDO Variable".

However, when I do that, it seems that a few extra characters are prefixed onto the data value in the cookie for some reason. Like "GA1.2." and then followed by the actual value of the ClientID.

What would I need to change in order for this to function as a UDO variable type of variable instead of as a cookie-type variable? Is it just a matter of how the variable is referenced (utag.data._ga)?

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

Hi @Krasner,

we have implemented this as well, so maybe I can help. The reason why changing the variable type to cookie-type works is because you then read the cookie which GA uses to store the client id directly. However, as this an implementation detail its direct usage is not recommended by Google (https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id#getting_the...) and you should use the api provided by the ga object to get the client id.

You can use the solution provided by Dan, but as the function can only run when the ga object is initialized the pageview for the current page is already sent. This means that you have to fire a second hit to ensure that the client id is sent to GA. To prevent a bloating of our GA hits we chose to use the solution provided in your first post via the custom task and to modify the GA tag template (as there is currently no mapping for the custom task in the template).

We added the follwoing code to the loop in the initTracker() function:

u.o(c.name + '.set', 'customTask', function(model) {
    model.set('dimension1', model.get('clientId'));
});

We would prefer not having to modify the template, but as long as Tealium does not provide a mapping for the custom task we think it is the best solution for us.

Best regards,

Andreas

 

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

After working with Tealium support, we implemented a variation of the solution @ahrasch provided. As described, we used a custom task. However, we did this in an extension, rather than by modifying the tag template. And to supplement this, for the possible occasions where timing causes the tag to fire before the value is provided, we are also storing the value in a session cookie. In this solution, there is still some possibility of the Client ID not being captured on the very first pageview hit, but so far we are seeing it capture 100%, and we also know that most of our pages have at least one event hit after the pageview.

So, the solution involves creating one first party cookie variable (as utag_main_gaClientId), mapping this to the custom dimension in the tag (we used custom dimension 9, after creating this in our GA property settings), and then creating the following javascript code extension, scoped to our GUA tag only:

ga(function() {
var trackers = ga.getAll();
for (var i = 0; i < trackers.length; ++i) {
var tracker = trackers[i];
var trackerName = tracker.get('name');

ga(function(trackerName) {
utag.data['client_id'] = tracker.get('clientId');
utag.loader.SC("utag_main", {"gaClientId": utag.data['client_id']+";exp-session"});
ga(tracker.get('name') + '.set', 'customTask', function(model) {
model.set('dimension9', model.get('clientId'));
});

});
}
});

Get Google Analytics Client ID and map to a GA custom dimension

Bronze Contributor
Bronze Contributor

Hi @ahrasch

any idea how you would translate this code to work with the new gtag.js.

it does not seem to have an initTracker function that references the tracker!

Thank you

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

Hi @salih

I am not familiar with the new gtag.js, as I don't think it is very useful when already using a tag manager. Also, it does not seem to be feature complete yet in comparison with the old analytics.js. The custom task used in my solution is not mentioned in the gtag.js documentation, so I don't know if it is supported at all.

Best regards,

Andreas

Get Google Analytics Client ID and map to a GA custom dimension

Bronze Contributor
Bronze Contributor

Hi @ahrasch,

Where in the initTracker() loop did you add that code?  I've placed it at the very end of the loop; is that the correct place?  I've attached the picture here:

Tealium Client ID Tracking.PNG

Hope to hear from you soon, thanks!

- Dustin

 

 

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

Hi @DChen721,

this is exactly how we did it. You can only set properties on the ga object after the tracker has been created, so it has to be at the end of the loop.

Best regards,

Andreas

 

P.S. You maybe should also check your version of the GA tag template. In our case, the adddition is around line 170. So it seems the tag template you are using is quite old and maybe you want to update it before adding the code (see https://community.tealiumiq.com/t5/iQ-Tag-Management/Managing-Tag-Templates/ta-p/21713).

Get Google Analytics Client ID and map to a GA custom dimension

Bronze Contributor
Bronze Contributor

Hi ALL, 

I thought I would post the solution I ended up with because it's in response to @salih question around gtag and I really struggled with this for a while... Guessing a few folks have also. 

This is an elegant fix, that doesn't use tag template edits

Firstly... Passing clientID into GA through the mapping tool is always problematic, because on first page view on a new browser/client, the GA call needs to generate both the clientID and issue a pageview at the same time. Therefore requesting the clientID (or lifting it from the cookie) is an issue, because this information is only available after the first pageview. It needs to occur internally within the tag generated call. 

HOWEVER, using the mapping is also the fix for this situation AND any GA generated values that needs to be passed to Custom Dimensions/Metrics with the tag generated hit (pageview/event or other), see https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets (for background)

The fix goes like this;

  • If you are using Audience Stream, you will need to surface the clientID to the datalayer anyway. My recomendation is to do this with the first party cookie element in the Datalayer, use this script to acquire the raw clientID
    if ( b.hasOwnProperty("cp._ga") ) { 
        b.ga_cid = b["cp._ga"].split(".")[2]+"."+b["cp._ga"].split(".")[3];
    }
    PRO: asside from first pageview, the cookie is already browser-side, and can be executed straight away.
    CON: on first pageview, this script wouldn't execute (cookie won't be present yet). However, I'll post a cookie listener in this thread that solves this, AND I've timed getting the id from the GA object over cookie generation and they are within 30ms of each other.
  • Even if you don't need the clientID for any other solution, I would still encourage you to collect it in the datalayer anyway (as we at least need a placeholder for the mapping). For the sake of this example, let's call it "ga_cid" (use something that supports you naming convension).
  • Now, in the Google Analytics (gtag.js) Tag, go to Data Mappings and select the "ga_cid" variable, and press select destination
  • Select Dimensions from the Category list in left column.
    • For ClientID we will select All Page Hits from the Event Type drop down
      NOTE: You can use this method for other internal GA vars, and may scope the beacon type differently here
    • Select the Dimension number you choose to fill
      NOTE: If you need to fill a number higher than 20, select the last option and manually edit the result at top, after you have pressed +Add
    • For the name, you must type clientId (case sensitive).
      NOTE: The Tealium tag template places this string in the custom_map object within the gtag object, and even though it will create a corresponding key/value pair for it in gtag, Google ignores it for the internal var called 'clientID'.... This is the magic of this solution :-)

Save, publish, beer o'clock!

Get Google Analytics Client ID and map to a GA custom dimension

Bronze Contributor
Bronze Contributor

I realize this is an old thread, but I think there is an easier way to accomplish this with gtag.js. 

  1. Go to tag mappings
  2. In the variables dropdown select "Use Custom Value"
  3. Type in "clientId" in the top left hand input box. This value really doesn't matter. 
  4. Click "Add Custom Dimension" 
  5. Type in "cdm.dimensionXX-clientId"
    1. Replace "XX" with the custom dimension number you want to populate. 
  6. Click Done, Apply and Publish. 

 

Get Google Analytics Client ID and map to a GA custom dimension

Silver Contributor
Silver Contributor

Hi @Krasner 

This solution doesn't work well for me.
The very first hit of a new session doesn't get the clientId, and it's the only important one, for the other hits we can get the "_ga" cookie value...

I don't know how this case is not OOTB for the analytics.js tag...

Get Google Analytics Client ID and map to a GA custom dimension

Tealium Expert
Tealium Expert

Hi All

Making a couple of assumptions on use case here, however the need for this over most use cases is decreased now that GA have exposed their client id field in the core reporting api -  ga:clientId

Prior to this, 

With regards to 1st hit/post 1st hit usage - we scoped the custom dimension to session. 

A post tag loop listening for the cookie drop, then fires a non-interactive hit giving us a completion for the 'bouncers' or single page no interaction sessions. 

Hope that helps. 

G

Research your Experience | Improve and Evolve | Leave no one behind
- Don't forget to mark a solution as accepted if it hits the mark -

Get Google Analytics Client ID and map to a GA custom dimension

Gold Contributor
Gold Contributor

@jared_empirical wrote:

I realize this is an old thread, but I think there is an easier way to accomplish this with gtag.js. 

  1. Go to tag mappings
  2. In the variables dropdown select "Use Custom Value"
  3. Type in "clientId" in the top left hand input box. This value really doesn't matter. 
  4. Click "Add Custom Dimension" 
  5. Type in "cdm.dimensionXX-clientId"
    1. Replace "XX" with the custom dimension number you want to populate. 
  6. Click Done, Apply and Publish. 

 



Did this actually work for you @jared_empirical? Because it does not for me.

CORRECTION: I had an issue with my Fiddler... :) Amazing, thanks!

Get Google Analytics Client ID and map to a GA custom dimension

Bronze Contributor
Bronze Contributor

This worked well for me, except that I needed to add an extra "-" in the end of the destination name "cdm.dimensionXX-clientId-".

If I try this without the "-" or with a "-all" in the end, the dimension gets the value from the Custom field.

But thanks for the help

Get Google Analytics Client ID and map to a GA custom dimension

Bronze Contributor
Bronze Contributor

Has anyone come up with a method to grab the clientId from a ga4 tag and set it to a custom event parameter? If so, how? The above mentioned method to access the gtag.js doesn't cut it for ga4.

...and once I have it on tag level, how do I push the clientId value to a data layer variable?

Regards, Julian
Public