• Courses
    • Courses
    • Course bundles
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
    • GA4 community
  • About
    • About
    • Contact
  • Login
  • Courses
    • Courses
    • Course bundles
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
    • GA4 community
  • About
    • About
    • Contact
  • Login

June 1, 2020

A Guide to Google Analytics User ID in Google Tag Manager

Note: this blog post is using Universal Analytics (GA3). If you are looking for Google Analytics 4 examples, read this.

Update: June 1st, 2020. If you’re looking at Google Analytics user metrics you need to understand one thing: the number of users does NOT represent the actual number of people visiting your website. It’s the number of different browsers that were used to visit your website/shop/etc.

That’s because when a visitor lands on a page for the first time, Google Analytics assigns a unique Client ID for that visitor (by storing in a cookie). As the visitor progresses and continues navigating, that Client ID persists across pages and lets GA understand that it is still the same visitor browsing pages.

However, if that very same visitor switches to another device or at least to another browser on the same device, Google Analytics will store a new Client ID (because they are not persisted across devices). And that’s the main reason why your GA User metrics, by default, are inaccurate and too big.

So what can you do? You could use the User ID feature in Google Analytics in order to reduce the effect of the same user + different browsers. And in this exact guide, I’ll show you how to use a User ID in Google Tag Manager (including how to get the ID and how to send it over to GA). Additionally, I’ll share a bunch of techniques on how to acquire the User ID as a variable in Google Tag Manager.

 

Table of Contents

+ Show table of contents +

  • #1. What is User ID feature in Google Analytics?
  • #2. Enable User ID features in Google Analytics
    • #2.1. Enable User-ID reporting
    • #2.2. Create a User-ID reporting view
    • #2.3. Send User ID with Google Tag Manager to Google Analytics
  • #3. How to get User ID in Google Tag Manager?
    • #3.1. Not everything can be a User ID
    • #3.2. Method No.1: asking a developer to push the User ID to the Data Layer
      • #3.2.1. Storing the ID in a cookie
    • #3.3. Method No. 2: Fetch the User ID from the already existing cookie
    • #3.4. Method No. 3: JavaScript Variable
    • #3.5. Method No. 4: DOM Scraping
    • #3.6. Honorable mention: Fetch User ID from the URL
  • #4. Update Google Analytics Settings Variable
  • #5. Time to test:
    • #5.1. Check the Preview and Debug console
    • #5.2. Check with a browser extension
    • #5.3. Check GA real-time reports in a User-ID view
  • #6. GDPR and visitor’s consent
  • #7. User ID as a custom dimension
  • #8. Final words

 

#0. Before we continue: this topic is explained in the Intermediate GTM Course

If you think that this blog post was too complicated and you prefer video material, enroll in my Intermediate Google Tag Manager course where you will learn various GTM tricks and how to set up useful features (just like User ID in GTM).

Enroll in Intermediate Google Tag Manager course

 

#1. What is the User ID feature in Google Analytics?

User-ID lets you associate a persistent ID for a single user with that user’s engagement data from one or more sessions initiated from one or more devices (and, of course, browsers).

When you send Google Analytics an ID and related data from multiple sessions, your reports tell a more unified, holistic story about a user’s relationship with your business.

Not only will User ID make your general User Metrics more accurate but it will also unlock a new set of reports/data:

  • It modifies the data in the Audience > User Explorer report (replaces the Client ID with your provided User ID)
  • Unlocks the Audience > Behavior > User-ID Coverage report (where you can see how many visitors have the User ID assigned vs unassigned)
  • Unlocks Audience > Cross-Device reports that show:
    • How devices are overlapping (e.g. how many users browse with desktop AND mobile devices)
    • Device paths (the idea is pretty similar to the Top Conversion Paths (in the Multi-Channel Funnel reports) but it shows what are the most popular device sequences among your visitors (e.g. first they browsed with the mobile device but eventually made a purchase on a desktop).
    • Acquisition devices (shows the originating device (that was used to initially land on your website) and whether that very same device was used to convert).

Keep in mind that the bullet points above apply only to the User-ID GA View (continue reading and I’ll explain what it is). But still, the User ID feature makes User Metrics a bit more accurate even in non-user-id views.

 

#2. Enable User ID features in Google Analytics

There are three ingredients you need for this to work:

  • Enable User-ID reporting in Google Analytics
  • Create a view specifically for the data with the User ID
  • Send a user ID to Google Analytics with Google Tag Manager from your website/shop/etc.

There are also some legal things you need to keep in mind but I’ll mention them a bit later in this guide.

 

#2.1. Enable User-ID reporting in Google Analytics

To do this, you’ll need to have Edit permission for the GA property.

Sign in to your Google Analytics, choose the property you want to edit, and go to Admin. Then, in the Property column, click Tracking Info > User-ID.

  • Read the User-ID Policy
  • Agree to the User-ID Policy
  • Click Next Step

After that, you’ll see a page with some instructions and codes. Skip this for now by clicking the Next Step.

In that step, you might also notice a Session Unification option. It is recommended to keep it enabled. Session Unification allows you to collect as much data as possible. Hits collected in a session before a user logs in will be assigned to that user’s Unique ID after the subsequent login.

 

#2.2. Create a User-ID reporting view

In that very same Google Analytics property, create a new view. You can either do that by clicking the Create button in that very same wizard:

…or go to the Admin section, View column, and click Create. Enter the reporting view name, choose the time zone and under the Show User-ID Reports, set the switch to ON. Click Create.

Important: you can create multiple User-ID views in the same property (usual view limits apply) but you cannot convert standard views to User-ID views and vice versa.

 

#2.3. Send User ID with Google Tag Manager to Google Analytics

The third ingredient (send the Google Analytics User ID with Google Tag Manager) is a larger one. In fact, the largest chunk of this guide is dedicated only to that.

 

#3. How to get User ID in Google Tag Manager?

Sending User ID to Google Analytics (with Google Tag Manager) is pretty easy. Getting/fetching it beforehand might be a challenge (depending on the nuances of your project). In this guide, I’ll mention several tips/techniques on how you can get the User ID in Google Tag Manager and then forward it to Google Analytics.

Keep in mind that the majority of these techniques are not universal, meaning that some of them might work for you while others won’t. Their usefulness solely depends on a website you’re working on, your team, your client’s capabilities, etc.

 

#3.1. Not everything can be a User ID in Google Analytics

It’s really important to understand that Google Analytics’ Terms of Services do not allow tracking PII (Personally Identifiable Information), such as Email Address, Social Security Numbers, etc. stored on their servers. The same principle applies to the User ID. Even if you use email addresses to identify users in your system/CRM/etc., you cannot use email as a User ID in GA.

However, you can still use less readable User ID from your system (that consists of random numbers, letters, etc.) e.g. 1234567 or 123aboasdb2234. These are acceptable User IDs that you can use in Google Analytics.

But you might say Hey, aren’t such IDs still PII? I can look that ID up in my CRM and still identify the visitor. 

Well, yes, you can. But GA allows that. Kind of a gray area but the industry aligns with it. So don’t panic and use them. To sum up:

  • [email protected] – CANNOT be used as a User ID in Google Analytics
  • 5239asbd923fade923da – CAN be used as a User ID in Google Analytics.

I think I made my point clear here. Let’s proceed to some cool stuff, getting User ID from somewhere and then using it in Google Tag Manager.

#3.2. Method No. 1: Asking a developer to push the User ID to the Data Layer

If your website has an authentication feature (login), then you can ask a developer to push the User ID to the Data Layer. You can hand him/her the following code:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event' : 'login',
  'userId' : '1234567' //this number must be replaced with an actual User ID
})

If you’re working on a regular website (that refreshes the entire page when the user is navigating), then it’s preferred to have this code placed above the GTM container (that way, you’ll have it available even with the All Pages GTM trigger).

If you’re working on a Single Page Application, then the location of this code does not really matter. Also, the ‘event’ parameter is not required. But if it is implemented, you can use it as a trigger to track Login events.

Another useful thing would be to ask a developer to push the User ID every time new page loads (I mean when the page entirely refreshes and the previous values in the Data Layer are wiped out). Then the code could look like this (placed above the GTM container snippet):

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'userId' : '1234567' //this number must be replaced with an actual User ID
})

After a developer starts pushing the User ID to the Data Layer, get back to your Google Tag Manager account, go to the container of the website that you’re currently working on and enable Preview and Debug mode.

Now, head over to your website, refresh it (while being logged out of that website), and log in. After you successfully authenticate, a login even should appear in the Preview console. Switch to the Data Layer tab of the Preview console and keep looking for the userId parameter. It should contain some value (the actual User ID).

Even though the User ID is in the Data Layer, you cannot simply use it in your tags or triggers without actually turning that piece of information into a GTM Variable. That’s why you need to create a Data Layer Variable for that User ID.

Note: Data Layer Variable Name (the field that I’ve highlighted in the screenshot above) is case-sensitive. So if there is a userId (with the uppercase I) parameter in the Data Layer, you must also use the uppercase I in variable’s name (in GTM user interface).

 

#3.2.1. Storing the ID in a cookie

If you want to go one step further, you can store the User ID in a cookie. Simo Ahava has already posted a guide on this topic so I borrowed his idea. Here’s how it goes:

  • A visitor logs in for the first time.
  • A developer’s code pushes the User ID to the Data Layer
  • A Custom JavaScript Variable checks if the User ID is in the DL and then stores it in a cookie. If the User ID is not in the DL, then the value of the Cookie will be used.
  • Finally, send cookie’s value with every GA hit

First, create a 1st Party Cookie variable (it will read the User ID if it is stored in a cookie)

The Cookie Name field is also case-sensitive. Where did that cookie come from, you ask? Well, from nowhere, yet. It will be set by a JavaScript code snippet that is displayed below.

Custom JavaScript Variable (Variables > New Custom JavaScript) with the following code:

function() {
  if ({{dlv - user id}}) {
    var d = new Date();
    d.setTime(d.getTime()+1000*60*60*24*365*2);
    var expires = 'expires='+d.toGMTString();
    document.cookie = 'userId=' + {{dlv - user id}} + '; '+expires+'; path=/';
    return {{dlv - user id}};
  } else if ({{cookie - user id}}) {
      return {{cookie - user id}};
  }
  return;
}

Keep in mind that if you named your variables differently rather than I did ( {{dlv – user id}} and {{cookie – user id}} ), you should also rename them in the script above.

So what this script does is that it checks whether the userId is present in the Data Layer. If yes, the script stores a cookie in a browser called userId. If userId is not found in the Data Layer, then the script will return the cookie’s value (and that cookie already contains the userId). If userId isn’t found anywhere, the variable will return undefined and user ID will not be passed over to Google Analytics.

Now, let’s pass the User ID with every Google Analytics hit. Open your Google Analytics Settings Variable and then click More Settings > Fields to Set. Enter the following values:

  • Field Name: userId
  • Value: {{that custom js variable you have just created)

If you named the Custom JavaScript Variable differently, then use that name in the value field.

P.S. According to Google’s User-ID policy, you must not session stitch authenticated and unauthenticated sessions of your end users unless your end users have consented to such activity, and such a merge is allowed under applicable laws and regulations.

In other words, if you plan to store the User ID in a cookie and track even unauthenticated users/visitors with the ID, then you need to get their proper consent (and also double-check with your legal team and local laws if that is ok).

So if you managed to ask a developer to push the User ID to the Data Layer and then created a variable for it (and, additionally, created a mechanism that stores the ID in a cookie), you’ve done the large part of the task. Feel free to skip to Chapter #4 of this guide where I’ll show you how to use that User ID in Google Tag Manager tag (Google Analytics).

 

#3.3. Method No. 2: Fetch User ID from the already existing cookie

There’s a chance that a website/shop/etc. that you’re working on already stores the User ID in a cookie. In that case, you could just read its value with Google Tag Manager and then (later) send it over to Google Analytics. If you have direct access to the developers of that website/shop/etc., ask them whether they store the User ID in a cookie and what is its name.

Otherwise, you can check this hypothesis by yourself. Go to your browser’s developer tools. I’m using Chrome so I’ll go to More Tools > Developer Tools.

Then go to Application > Cookies and choose the domain of your website.

Now browse and keep looking for a name that might be related to a User ID. There is no standard name for that thus various options are possible. Once you find something, it would be good to ask the client/colleague to confirm whether that’s the actual User ID.

So if you got lucky with the cookie (insert your fortune cookie pun here), memorize its name and go to Google Tag Manager UI > Variables > New (under the User-defined variables). Choose variable’s type, 1st Party Cookie and enter the name of the cookie here:

So if this User ID fetching method worked for you, Feel free to skip to Chapter #4 of this guide where I’ll show you how to use that User ID in Google Analytics tag (within GTM).

 

#3.4. Method No. 3. JavaScript Variable

I’ve explained this technique in a dedicated blog post so if you want to learn more, go check it out. Here’s a quick summary.

In short, the JavaScript variable lets you access the values of global JavaScript variables available on that page. For example, a browser language, the title of the current page, etc.

I’m not sure whether it’s always possible (pardon my limited programmer knowledge), but I’ve seen many cases where the User ID was also stored in a Global JavaScript Variable. So all you need to do is to find it.

How do you do that?

  • Option A: ask a developer who is involved with that website/shop/etc.
  • Option B: try to find it yourself.

Option A is easy and should always be your first choice.

Option B requires much more time. To start the search, go to the developer console of your browser (here’s the tutorial on how to do that on Chrome), type window and hit enter (like in the screenshot below).

window in console

Click the black triangle near the Window and you’ll see a list of properties that we’ll be able to access with a JavaScript Variable in GTM. Brace yourself, that list will be huge.

global js variables

Now, let’s imagine that you’re working with a Shopify online store. Intuitively, I’d scroll down and start looking for a shopify property. To save you some time, I can say that shopify property does not contain the User ID, however, ShopifyAnalytics does (I just had to spend some time looking for it).

Click the black triangle to expand the property and dig deeper. Unfortunately, I don’t see an ID anywhere, but there are some other possibly useful data points. Let’s dig even deeper. If you go to meta > page, you’ll find the customerId. This is exactly what you were looking for.

Now, head over to Google Tag Manager interface > Variables > New > JavaScript Variable and enter the entire path from top to the both that you followed to reach that customerId (window is not required). The final value of the variable must be ShopifyAnalytics.meta.page.customerId (case-sensitive). Every level is separated by a dot.

Save the variable, refresh the Preview mode (in the GTM UI), then go to the page and refresh it too (make sure you’re logged in to that website/shop/etc. as a user/customer). In Preview console, to Variables and check whether your JavaScript variable returns an actual User ID. If not, check for spelling mistakes in your JS variable.

So if this User ID fetching method worked for you, Feel free to skip to Chapter #4 of this guide where I’ll show you how to use that User ID in Google Tag Manager (Google Analytics tag).

 

#3.5. Method No. 4. DOM Scraping

This option is riskier due to its fragility (especially in websites where developers constantly implement improvements/changes/AB tests in the frontend).

In a nutshell, DOM scraping is a method to get a value from the website’s document object model by, well, scraping it. So if you, as a logged-in user, see your User ID displayed somewhere in the interface, you could fetch its value with help of DOM Variable or Custom JavaScript Variable in Google Tag Manager.

DOM Variable enables you to pick a website element and read its text or one of its HTML attributes (e.g. href, title, ID, etc.). You can pick an element by defining its ID (if such exists) or by using CSS Selectors. In order to make use of it, the knowledge of HTML and CSS Selectors is required. Also, be familiar with what DOM is in general.

There are millions of websites thus there might be millions of ways how that particular element is coded. If you’re lucky, maybe that element will have an ID:

In that case, it should be no brainer to use the DOM Variable with the following settings:

If there is no Element ID, you could then try to fetch the element based on its (and its parents’) CSS Classes.

That’s where the knowledge of CSS Selectors would come in handy. Speaking of the screenshot above, the user ID is a span element with the class username. Let’s pretend that we know that there are more elements on a page with the same class, thus we need to be more precise. This element is a descendant of the li element with ID wp-admin-bar-my-account. We can use this in our CSS Selector:

The CSS Selector I’ve used above means that I’m targetting elements that have a CSS class username and are descendants of an element with an ID wp-admin-bar-my-account.

Just don’t forget that several items on a page might be caught by the same CSS Selector. That’s why you should use the document.querySelectorAll() method to make sure that you’re fetching only that element that contains the User ID. Read the tip #18 in this guide to learn more.

Custom JavaScript Variable is much more flexible but also is more difficult to use because you need to know JavaScript. You can write simple (or complex) JS functions that will return the desired value (including the User ID).

But even if you don’t know JS, there is still a solution, GTM Variable Builder. This Chrome extension enables you to easily create Custom JavaScript variables that retrieve values of particular website elements.

How does it work? Open JavaScript console in Chrome, highlight any element on a website and click extension’s icon. What you’ll get is the JavaScript function that should be used in a GTM Custom JavaScript variable.

Get this extension

GTM Variable Builder Explanation

After you copy that ready-made function, paste it to the Custom JavaScript Variable in Google Tag Manager. It’s also a good practice to check whether this solution actually picks up only that one website element that contains your User ID.

Copy the first code that was generated by the plugin and instead of querySelector type querySelectorAll and enter this code in browser’s console. Hit enter. How many elements are returned? If one, then you’re good to go.

As always, when you create a variable, refresh the Preview and Debug mode in GTM. Then refresh the website that you’re currently working on and check the debug console. If your newly created User ID variable displays the actual value, then everything is working properly. If not, then check your CSS Selectors.

Public Service Announcement: However, this “hack” should be always considered as a plan B. It’s always better to actually know JavaScript, DOM, CSS Selectors. It’s much better to talk with developers upfront and ask them to push the User ID to the Data Layer rather than try scraping the website.

You see, when you’re using DOM Variable with the CSS Selectors (or a Custom JS variable generated by the GTM Variable Builder), you’re telling Google Tag Manager the exact path to that website element in the entire website document (e.g. from its parents to that very exact element).

Now if that path changes anywhere along the way (due to developer’s input or something else), your CSS Selectors or Custom JS variables will break and return undefined. Meaning that your User ID tracking in Google Tag Manager will stop working.

Nonetheless, in most cases, scraping is better than having/doing nothing. But if there is a slight chance of talking with developers, PLEASE PLEASE PLEASE do that and cooperate with them.

You + Developer + Data Layer is an unbeatable trio in tag management.

Anyway, if this User ID fetching method worked for you, Feel free to skip to Chapter #4 of this guide where I’ll show you how to use that User ID in Google Tag Manager (Google Analytics tag).

#3.6. Bonus: Fetch user ID from the URL

Even if your website does not have a login, you might be sending a newsletter to your visitors/users. You could take the Contact ID of the subscriber (from your Email Service Provider (ESP)) and user it as a User ID in Google Tag Manager and Google Analytics.

I won’t go into details but here’s the main idea:

  • If your ESP does not add Contact IDs in the URL when the subscriber clicks the link in your emails, then you could do that by yourself. Many ESPs support inserting attributes (a.k.a. Merge Tags) in emails and links. Benjamin from Loves Data mentions it in his video (@1:45)
  • When the visitor lands on a page, you could read the URL, catch the Contact ID (with help of URL Variable) and later store it in a cookie (just like it was done in chapter #3.2.1 of this guide). Just instead of the Data Layer Variable, you would be using the URL variable.

But keep in mind that this option should also be considered as a plan B and it will work only for those visitors who are clicking your email links with different devices.

 

#4. Update Google Analytics Settings Variable

Great. So far, we have enabled User-ID features in Google Analytics and learned several ways how to fetch the User ID in Google Tag Manager and turn it into a variable. Now we need to use it in our Google Analytics tags.

There are two ways: a bad way and a good way.

The bad way would be to update every Google Analytics tag in your GTM container and configure them to send User ID over to GA. I won’t even explain how that can be done because it is not the practice you should be following. By this day, you should have already migrated or come across to the GA Settings Variable.

The good way is to update your Google Analytics Settings Variable. Once you configure it to send the User ID, all Universal Analytics tags (that are using that variable) will automatically inherit that setting (unless you have done some exclusions on a tag level).

In your GTM container, go to Variables and choose the GA Settings Variable that you’re using in Universal Analytics tags. Expand More Settings > Fields to Set and enter:

  • userId
  • the variable (you have created in Chapter #3 of this guide) that returns the User ID. E.g if you chose the #3.2 method, then the possible name of the variable could be {{dlv – user id}}

The important thing here is that if you want to see every hit (events, page views, etc.) in the Google Analytics User-ID view, you need to pass the User ID with every hit. That’s why we’re configuring Google Analytics User ID on the level of the Google Analytics Settings Variable (and not just in the GA Pageview tag).

 

#5. Time to test

There are many options and tips but it’s fully sufficient to do the following:

 

#5.1. Check the Preview and Debug console

After you’ve updated the GA Settings Variable with the userId field, refresh the Preview and Debug mode, then go to the website you’re currently working on and reload the page. Then let’s check the Page view tag. Click Page view event in the left sidebar (or some other event upon which the Page View tag fires) and click the Universal Analytics tag.

Now scroll down a bit and check whether the userId field had the proper value. If not, there might be several reasons for that (depending on a method you chose to fetch the User ID.

Got undefined? If you got the User ID with the help of Data Layer Variable, it’s possible that User ID is not available yet on a Page view. Maybe a developer is pushing the User ID only after the DOM ready? Check that by clicking the DOM Ready event and going to the Variables tab. See if the value of your DLV is not proper. If yes, you should fire your Universal Analytics tag on DOM Ready instead of an All Pages trigger.

If you chose DOM Scraping, then the User ID will definitely not available with the Page view event. Fire your Universal Analytics Page view tag on DOM Ready trigger.

There are many reasons why your User ID variable returns an undefined value but the main idea here is that either you misconfigured a variable that fetches the User ID (e.g. spelling mistake) or that data is not available during that event yet. In the case of the latter, read this guide on how to properly debug with GTM(especially tip #8).

 

#5.2. Check with a browser extension (e.g. Tag Assistant or GA Debugger)

From what I’ve seen, the majority of GTM users (especially intermediates) use Tag Assistant or GA Debugger to test Google Analytics tracking. Let’ take a look how can you debug User ID in Google Tag Manager with these to extensions.

Tag Assistant. If you haven’t yet, install it here (P.S. here’s a more comprehensive tutorial). After you’ve installed the extension, a blue tag icon will appear in the top right corner.

Google Tag Assistant icon

By default, Tag Assistant is in the “sleep mode”, meaning that it does not check anything that’s happening on a page. In order to activate it, click the blue tag icon and then Enable.

Enable Google Tag Assistant

Now refresh the page. If any of Google’s products are implemented on that page, you’ll start seeing a particular number within that blue tag icon which represents the count of tags found.

Click the blue icon again to see a detailed list of all found tags. Then choose Google Analytics to get more details about, you’ll learn what data was passed, what could be improved, how many events were fired, etc.

If User ID was implemented correctly, you’ll see the ID right here (after you choose Google Analytics). P.S. You might need to scroll down a bit in the Tag Assistant window to find the ID.

GA Debugger. Once installed and enabled, this extension enables GA’s debug mode that starts displaying the data in the browser’s JavaScript console.

To enable it, simply click the extension’s icon and you’ll see the ON ribbon. This indicates that the GA Debug mode is enabled and you can start checking the data.

Then open browser’s JavaScript console and refresh the page. You’ll start seeing all the requests that were sent to Google Analytics.

Even though the info might look a bit too technical, this is definitely worth checking out as it (more or less) clearly displays all the parameters that were passed to Google Analytics (including the User ID). Keep looking for the &uid in the table and check whether its value is correct.

By default, browser’s console is cleared every time the page reloads. So if you want to preserve what was captured, enable Preserve Log setting:

 

#5.3. Check GA real-time reports in a User-ID view

Last but not least, let’s check whether the data actually reached its destination, Google Analytics. To do that, go to your Google Analytics User-ID view’s Real-time reports. Not just any view’s RT reports but a view with User-ID tracking features enabled.

This view displays only those hits that contain the User ID (&uid) parameter. Do you see your pageviews in real-time? If yes, then the testing is complete.

If not (even though GTM Preview mode and browser extensions displayed everything correctly), read this guide that will help you troubleshoot problems in Real-time reports.

 

#6. GDPR and visitor’s consent

If you’re tracking traffic coming in from the European Union (regardless of your business location), your User ID setup in Google Tag Manager is not ready yet. That’s because your User ID tracking in Google Tag Manager is not GDPR-compliant. Yet.

In a nutshell, GDPR (General Data Protection Regulation) is a law that requires consent from a visitor/user in order to process his/her PII (Personally Identifiable Information). User ID falls under this definition too. This means that you can set the User ID in a Google Analytics Settings Variable only if a visitor/user agrees to that.

I will not go into details what GDPR is (there are other great blog posts out there like this one, this one or this one).

Back to the User ID and GDPR. There are many tools and guides on how to implement consent banners on a website with Google Tag Manager (including this one). Here’s a quick summary of how such mechanisms work:

  • A visitor lands on a website
  • A banner (asking for consent to track/process PII) pops up
  • A visitor/user can agree or disagree to have his/her PII processed by your website/company
  • That consent is then usually stored in a cookie (also, it’s pretty common to push the consent data from the website/web app) to the Data Layer and access it via Data Layer Variable

Let’s imagine that on a sample website when a visitor/user agrees to have his/her PII processed, this consent is stored in a cookie and its value can be accessed in GTM with the help of 1st Party Cookie variable called cookie – consent to process pii. Possible values of that variable can be true or false. Remember, this is all just an example. In your case, variables and cookie names can be totally different.

If the value of that cookie is true (means that the consent was given), we should automatically insert the User ID in a Google Analytics Settings Variable. If false, our User ID variable should not be passed to Google Analytics.

In order to achieve this, we’ll need to use Lookup Table Variable.

Lookup Tables (and Regex Tables too) are awesome because they return different outputs depending on the value of the input variable. In this case, we can configure it to return the {{dlv – user id}} only if the value of {{cookie – consent to process pii}} variable equals to true. In other cases, the output will be undefined.

Keep in mind that in the second row of the table I used the Undefined Variable. Because if you left the output field empty, it would return an empty string and we want here to send no value at all (read undefined). You can learn more about the Undefined Variable here.

Another important thing is that in your case, the User ID variable might be different (not {{dlv – user id}}. Maybe it is {{cookie – user id}}. It depends on the situation. My point here is that you should insert YOUR User ID variable as an output (on the first row) in a Lookup Table if the consent of a visitor equals to true.

Save the changes and test. If a visitor/user gave the consent to process PII, then your Lookup Table variable should return an actual User ID. If the consent was denied, then the value should be undefined.

Finally, open your Google Analytics Settings Variable and replace the previously inserted plain User ID variable with that Lookup Table.

Save and repeat all actions (of testing) listed in Chapter #5.

In addition to this setup, you should update your Privacy Policy. Unfortunately, I’m not the right guy to ask for advice here. Go and discuss this with your legal department.

 

#7. User ID as a custom dimension

As of the beginning of 2019, Google Analytics still does not allow to build segments based on a User ID so if you want to debug only one visitor’s actions, User ID (as a dimension) will not be available.

However, that’s not a problem because you can pass the User ID as a custom dimension (CD) to Google Analytics. Simo Ahava has mentioned this CD in this guide (tip #1.4).

Once again, you must respect visitor’s/user’s privacy preferences and pass the CD only if the consent was given (meaning that you should use a Lookup Table here too).

 

Google Analytics User ID in Google Tag Manager: Final words

We’ve finally reached the end. In this guide, I’ve explained how to properly implement Google Analytics User ID with Google Tag Manager. In short, the process goes like this:

  • Enable the User-ID tracking features in Google Analytics + create a User-ID view
  • Find the way how to get the User ID as a variable in Google Tag Manager. There are many ways and I’ve shared several of them:
    • Data Layer Variable (+ later store it in a cookie)
    • Read the cookie that is already created by the website/platform/shop/etc.
    • User JavaScript Variable
    • Scrape DOM
    • Parse the ID from the URL and then store it in a cookie
  • Once you have the User ID as a variable in Google Tag Manager, set it as a userId field in Google Analytics Settings Variable.
  • If you have some visitor traffic from Europe, you need to abide by the GDPR and respect visitor’s/user’s privacy preferences. This means that the User ID can be passed to Google Analytics only after the consent is given. For that, we used the Lookup Table Variable.

With User ID, you will be able to see cross-device data and how visitors use them on your website/shop/etc. This can tell you a whole new story. Also, User ID improves the accuracy of user metrics in GA (even in views without User-ID tracking features).

Don’t panic if your User metrics will decrease, that’s exactly what you should expect. By default, every device and even every browser is treated as a separate user. With User ID feature, several devices will turn into one actual user.

Have any questions regarding User ID in Google Tag Manager? Did I miss anything? As always, comments are at your service.

Also, if you prefer video content over text, feel free to enroll in the Intermediate Google Tag Manager course where one of the topics is User ID tracking (with GTM)

Julius Fedorovicius
In Google Analytics Tips Google Tag Manager Tips
68 COMMENTS
Yarosav
  • Jan 17 2019
  • Reply

Great job! Thanks a lot for your time consumed and such a great result!

Bill
  • Jan 21 2019
  • Reply

Thanks for taking the time to write a great post. I think there is one aspect of the user ID that is not clicking for me and that is the generation of the number string used for the user id. So in your below coding example, you have the user ID set to 1234567. Will this string of numbers be randomly generated or how will a different string of numbers be generated for each user who in my case logins into a customer portal (username and password combo)? Thank you.

window.dataLayer = window.dataLayer || []
window.dataLayer.push({
'event' : 'login',
'userId' : '1234567' //this number must be replaced with an actual User ID
})

    Julius Fedorovicius
    • Jan 21 2019
    • Reply

    You are not the one who randomly generates that ID. It's the developer's responsibility to push here the exact User ID that is used in your customer portal. The structure and content of the ID solely depend on how that Customer Portal is developed. It might be a random number, random letters, timestamp, etc.

    Josh May
    • Jan 21 2021
    • Reply

    Thank you for asking this! and the helpful answer!!

Matt
  • Feb 7 2019
  • Reply

Quick question. First great article, my question is can this be done if my company doesn't have a CRM? Thank you.

    Julius Fedorovicius
    • Feb 7 2019
    • Reply

    The most important thing that somewhere you need to have user ID stored. When the user logs in to his/her account, his/her user ID must be pushed to the Data Layer. CRM is not the only source where those IDs can be stored. Your website's/application's database is the first place where User IDs should be available.

Jose
  • Mar 15 2019
  • Reply

Hi Julius.
I dont know what can i do.
I have a domain (www.example.com) and a subdomain (shop.example.com)
Both with the same analytics ID (FROM 2 DAYS AGO) implemented with the same GTM container with the plugin DuracellTomi's.
My problem is when i make 3 views.
-1 view for www.example.com (with filter only traffic from www.example.com)
-1 view for shop.example.com (with filter only traffic from shop.example.com)
-1 view with both www.example.com and shop.example.com

In GTM cookieDomain is set in auto by default in the analytics ID variable
I added to Referral exclusion list "example.com"

So why if we take the data from view www.example.com and view www.example.com are not the same as view with both?

Should i add to referral exclusion list www.example.com and shop.example.com or its fine with example.com

Sorry for the long question ...

    Julius Fedorovicius
    • Mar 18 2019
    • Reply

    You need to be more precise. What is different? There might be other configurations as well made in those views that are affecting your data.

Roman
  • Mar 28 2019
  • Reply

Hi Julius, thx for the great article! Really usefull.

One question. You write: "Another useful thing would be to ask a developer to push the User ID every time a new page loads"

Is it obligatorily? Or it`s just a tip and it is enough to push the User ID only once, after login?

    Julius Fedorovicius
    • Mar 28 2019
    • Reply

    Hi, User ID must be passed with EVERY hit to GA. So if I log in and then go to another page, then the User ID still must be in the Data Layer (unless you store the ID in the cookie as well).

      Mahjabeen Khan
      • Nov 23 2022
      • Reply

      Hi Julius. Does it also mean that once the user logs out, we need to stop pushing the user_id variable to the data layer?

      I want to analyse user behaviour when a user is logged in and when not logged in. This implementation would help set this up.

Sarah Walker
  • May 2 2019
  • Reply

Hi Julius,

Thanks so much for this! It's been a lifesaver, but I do have one question. Now that all of this is done, how do I see the data? The user explorer shows client ID by default, so I'm guessing it involves a custom report?

    Julius Fedorovicius
    • May 3 2019
    • Reply

    Hey, you need to create the User ID view in your GA property.

      Sarah Walker
      • May 3 2019
      • Reply

      I have the User ID view set up, but it shows Client IDs in the User Explorer. Did I miss a step?

        Sarah Walker
        • May 3 2019
        • Reply

        Never mind! Created a new view and it's fine. Thank you again!

lironv
  • May 6 2019
  • Reply

hey

i have an angular project.
My GTM code is in the index.html inside the HEAD. when i put the dataLayer.push() before the gtm code so everything is going right and i can see the userId value, but if i put the dataLayer.push() in the login function (which run after the page loaded (spa) when the user click on signin) so the GA variable is undefind (in the dataLayer the value is correct).

any help?

    Julius Fedorovicius
    • May 8 2019
    • Reply

    This happens because you fire the GA Pageview tag before the User ID is present in the Data Layer. If the ID is not in the Data Layer, then it makes sense that the "undefined" value is sent to GA.

    You need to find a solution in your code how to send the User ID before or in the exact moment of a pageview (or virtual pageview).

Julius Fedorovicius
  • May 10 2019
  • Reply

Maybe you're passing the user id only with pageview? It must be passed with everything you send to ga: pageviews, events, etc.

Eli
  • May 10 2019
  • Reply

Wow! thanks for the fast reply. I've add the user id field to my google analytics variable, so it should done for all the tags that I have, right?

Andrew Arnov Setyawan
  • Jun 17 2019
  • Reply

Does the GTM track the user behavior before logged in? how about the marketing platform attribution? does it work the same in the GA?

TIA!

    Julius Fedorovicius
    • Jun 18 2019
    • Reply

    Can you elaborate/rephrase your question? If you set GTM to track a visitor before the login, then it will

Ashutosh
  • Jun 26 2019
  • Reply

Hey, Thanks for the information. I have implemented this step by step, but the issue is I can see that I am passing userId from my site in the preview mode. But I can't see the userId in my UserId view report.

    Julius Fedorovicius
    • Jun 26 2019
    • Reply

    1. Triple check if you are actually sending the user ID to GA (via browser's network tab).
    2. Triple check if you have actually enabled User ID features and you are actually viewing it.
    3. Real-time report shows pageviews and events. If you're trying to view other interactions, you won't see them.
    You can also check this guide https://www.analyticsmania.com/post/google-analytics-real-time-reports-not-working/#gref

Giovanni
  • Oct 31 2019
  • Reply

Nice guide, may i ask you why to use a push when you can just declare the array?
dataLayer = [{'userID': '123'}];
Thankyou

    Julius Fedorovicius
    • Nov 4 2019
    • Reply

    Hey, read this https://www.analyticsmania.com/post/datalayer-push/

Romain Priot
  • Mar 25 2020
  • Reply

Hello Julius,

Thanks for one of the most comprehensive guide available.
Now that I have User ID, I'd like to know if it's possible to filter OUT User ID trafic from a GA view ?

So I can have real time reports excluding logged in Users, for instance.

Cheers,

    Julius
    • Mar 25 2020
    • Reply

    Send user id as a custom dimension. And the use that in a filter.

Ric
  • Mar 26 2020
  • Reply

Hey Julius, could this be tested on not owned domains, with the container injector, and so skipping the part of activating it on GA?

If so, when there is a unique CSS element, which identifies a user on the DOM, most of the times that should work out to obtain the User ID with the CSS selector method plus its Element Selector, isn't it?

I'm getting a null again and again.🤔

    Julius Fedorovicius
    • Mar 26 2020
    • Reply

    No, you need to enable the User ID feature inside of GA property and create a separate User-ID view.

    As for the second question, I don't understand it. It sounds like you are mixing definitions. I know that you have access to my Intermediate GTM course :) Check the following resources there:
    - DOM Element Variable lesson
    - Auto-event Variable lesson
    - CSS Selectors module

    After completing them, you should get a better understanding + the CSS selector module offers a quicker way to learn CSS selectors.

    If you are getting null in your DOM element variable this means that either your CSS selector is incorrect or an element is not present on a page.

Ric
  • Mar 26 2020
  • Reply

What I meant in the 2nd paragraph, is that having the user ID in a span element with a unique class on the page, I should be able to obtain it right away.

I'm following the DOM scraping method for this specific case.

    Julius Fedorovicius
    • Mar 26 2020
    • Reply

    You can access any element that is present on a page if your CSS selector is correct.

Nayan
  • Jul 1 2020
  • Reply

Hi,
I am a developer and I want to know How to push this "5239asbd923fade923da" format in the data layer if there are multiple users logged in on my website.

Could you please tell me the format of this "5239asbd923fade923da"?

    Julius
    • Jul 1 2020
    • Reply

    Hi, This is just a random example. There is no format here.

Yogendra
  • Jul 14 2020
  • Reply

Hello Julius,

Thank you for sharing the userid implementation, It is very helpful.

I can see the userid getting tracked in userid view of google analytics only when tag manager preview mode is on. Else I cannot see any data getting recorded. Can you suggest me solution for this?

    Julius Fedorovicius
    • Jul 14 2020
    • Reply

    Hi, publish the container.

Yogendra
  • Jul 14 2020
  • Reply

The container is already published even though I cannot check any data.

Coming to a custom dimension, is it mandatory to implement to push user-id data to analytics. If yes, I have used the same index value in google analytics & Tag manager with scope as a user. Here is the problem, how to implement this with "JavaScript - Universal Analytics properties" Help me with this.

Felipe
  • Jul 29 2020
  • Reply

Hi Julius, first off all, thank you.

i implement version 3.2 as you mention to use same variable names, but when i try to Submit, i got an error:

Variable circular dependency

There is a circular dependency involving variables.
Please inspect the variables in the list and remove the circular dependency.

do you have any tip how to solve this?

Felipe
  • Jul 29 2020
  • Reply

i just found the issue. thank you

    Julius
    • Jul 29 2020
    • Reply

    This means that you have inserted one variable in itself. Inspect your setup and remove that issue. You configured something incorrectly, re-read the guide once again and try to identify the issue.

Ali Silat
  • Oct 8 2020
  • Reply

Hi Julius, Great article. I am working on a site where we only have a guest checkout option, no account needed. How do I get UserId for anonymous users? Does UserId work only with account-level websites? What do you suggest for this type of website? We only sell one type of product, and we haven't implemented account feature.

    Julius
    • Oct 8 2020
    • Reply

    Nothing. User-id feature is for websites where visitora can log in.

Burana
  • Oct 14 2020
  • Reply

Hi Julius,

Thank you for the comprehensive article, I'm using cookies for the userID and it worked fine with "all page view" in GA, but none of the data showed in the "User ID View". I've checked all the steps and process and everything seems right. Is it because of I'm not using the Datalayer userID?

Conny
  • Nov 2 2020
  • Reply

I'm trying to do this for the new GA4 where the tracking ID's hasa different format (doesn't start with UA). When trying to add the userId field to Google Analytics Settings Variable it complains that the tracking ID doesn't start with "UA-". Is there another process or way to do this for GA4?

Jsiva
  • Nov 2 2020
  • Reply

Hi Julius,

I'm following your steps to create the user tracking by DLV and cookies variables. Unfortunately, I cannot see userID in Preview and Debug console. The GTM is newly built and I have only created a GA page view tag in the account. Did I miss anything? I have tried few times but still couldn't figure out the issue...

I'm using a wordpress plugin called "google tag manager for wordpress" to push the user id to data layer.

Hope to hear from you soon. Thanks a lot!

    Julius Fedorovicius
    • Nov 2 2020
    • Reply

    You need to enable user ID in the plugin's settings: Basic Data > Visitors > Logged in user ID

      Jsiva
      • Nov 2 2020
      • Reply

      Thanks for your quick reply.

      Basic Data > Visitors > Logged in user ID
      >> yes, I have done that already

    Jsiva
    • Nov 2 2020
    • Reply

    FYR https://pasteboard.co/JyuYmPg.png

      Julius Fedorovicius
      • Nov 2 2020
      • Reply

      I recommend to re-read this guide once again because you haven't configured the User ID in your tag (based on your screenshot). If you have, then refresh the preview mode (reload it)

        Jsiva
        • Nov 2 2020
        • Reply

        I re-read and tried to create it again, but it still didn't show in tag but only in variable.

        It would be great if you can help me to take a look on the settings. Thanks for your help again!

        https://pasteboard.co/JyvuEQ4.jpg

          Julius Fedorovicius
          • Nov 2 2020

          Well, I can see the user ID in your screenshot. It's under the fieldsToSet.

          But your tracking ID field is configured totally incorrectly. That field accepts only a UA-XXXXXX value, not some complex objects. Fix it.

        Jsiva
        • Nov 2 2020
        • Reply

        That's a variable for the the GA tracking. Anyway, I have replaced it with the actual GA tracking ID (UA-XXXXXX), but it still doesn't work. Is there any other reasons?

          Julius Fedorovicius
          • Nov 2 2020

          It's difficult to debug without seeing the website and having access to your preview mode. If you want, you can book a 30-minute call here and we'll get this resolved https://analyticsmania.com/call

Srinivas
  • Apr 18 2021
  • Reply

Hi,
If I store user-id in a cookie, then if a user logs in incognito mode, it wont be tracked right?
In that case, is it better to store it as a data layer variable?

    Julius
    • Apr 18 2021
    • Reply

    Correct. But a developer is needed here to push the user id to the data layer.

Troy
  • May 24 2021
  • Reply

It is not obvious how to enable User-ID reporting in GA4 properties.

In section #2.1. Enable User-ID reporting in Google Analytics, the Admin settings properties directions regarding Tracking Info > User-ID seem to only exist for legacy UA properties.

How do you achieve similar configurations for GA4?

    Troy
    • May 24 2021
    • Reply

    Note, I'm using the dataLayer injection method from #3.2 to pre-populate the dataLayer with the userId. I'm then including it via an additional settings field on the GA4 configuration for all GA4 tags. As a test I also created a Google Analytics settings variable to point to a legacy UA property however we are attempting to convert to GA4 properties for reporting.

Laura Douglas
  • Aug 13 2021
  • Reply

Thanks for sharing your amazing content with everyone!

Question:
1) Is it required to use "userId" as the data layer variable name and the field name on the Google Analytic Settings "Fields to Set">"Field Name"? Does Google Analytics rely on it being called "userId" for some reason? I wanted to use "UserLoginMappedToUserID" as the data layer variable name and in the Google Analytics Settings.

2) For the custom dimension in Google Analytics, do you need to use "userId" exactly?

    Julius
    • Aug 13 2021
    • Reply

    That is "no" to both questions

Koushik
  • Oct 13 2021
  • Reply

Hi Julies I am stuck with some task. I have registration page in my website but After complete registration page redirect to /homepage, also if existing user normal sign in - that time land on /homepage.

I am facing issue in Goal tracking. my registration traffic & normal sign in traffic mixed in Goal..

How to create Dummy URL server call through in Google tag manager?

Sam Chen
  • Oct 18 2021
  • Reply

Hi Julius,

I recently read several blog posts from you. They are fantastic. In one blog post, you think GA4 is still a beta version and inmature, and UA is mature, and suggest "parallel tracking", i.e., use both GA4 and UA to track the same website, they will not interfere each other. Now, my website is taking in your suggestion and using both GA4 and UA to track data.

Now, except for reading this post, I also read another post for GA4 user ID. I find that their data layer is actually same, in GTM, "userId", "dlv - user id" are also same. My question is, can this data layer be used for both GA4 and UA?

Another question is, in my UA account, I have a "Sign In" goal (not event) for login, in my GA4 account, I have event "sign_in" for login. But in your data layer, part of them is like below:

.....................
window.dataLayer.push({
'event' : 'login',
......................

Should I change as 'event': 'sign_in'? Or just use it, and don't need to make any change?

Thanks

Jana
  • Nov 18 2021
  • Reply

Hi Julius, In the topic "#5.1. Check the Preview and Debug console" we can see de id value. I configured de userId as an event=login. Is it why I can´t see the id value in the GA tag? Is it this ok?

    Jana
    • Nov 18 2021
    • Reply

    In addition:
    - We are using the dlv user id, seens correct (I read a lot of Analytics mania posts to check if dlv is configure correctly.)
    - The user id value appears in the event tag "login".
    - GA tag is fired in "Container Loaded" not in "Page View" as in the example above. This is somenthing about the GTM version? Or something incorrectly?
    - Looking directly in GA, User-Id View, User explore report, we can see de users id there.
    - Actually GA seems to be correct, but this point about not having the user id value in the GA tag during preview mode, worried me and this made me research over 6 hours on this single issue. I hope you can help me, thank you in advance!

Charles M
  • Jan 28 2022
  • Reply

Hi Julius,

In GTM preview I see the userID field and value populate correctly in the "Tag Details" view within my "Google Analytics Settings" property variable.

In the new GA "User ID View" under "Realtime" should I see the same userID value pull in while in GTM preview mode? If so, where should I be looking for the userID value as I've checked Overview, Locations, Traffic Sources, Content, Events, and Conversions?

Any insight you can share on how to confirm GTM is passing the userID variable to GA in the Google Analytics dashboard would be greatly appreciated!

    Julius Fedorovicius
    • Jan 31 2022
    • Reply

    The fact that you see yourself in the user id view's realtime report is a confirmation. You won't see the actual value in realtime or other reports you mentioned. But you can check it later in the user explorer.

Chandu Aki
  • Mar 19 2022
  • Reply

Which is the best practice among sending userID in data layer variable GTM over sending userID in the GA4

Chandu Aki
  • Mar 19 2022
  • Reply

Initially there is no userID for the user , after login we are assigning the userID to the user

In the segment, when the ID is assigned to the user, it will be automapped with the latest ID

Can we expect the same in the GTM / GA4?

Please add your thoughts

Skylanche
  • Aug 27 2022
  • Reply

Hello Julius I would like to track the user id using the data layer method 3.2 must it be added on all pages of the website above the gtag container

    Julius Fedorovicius
    • Sep 22 2022
    • Reply

    Yes

Leave a comment Cancel reply

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

 

Hi, I'm Julius Fedorovicius and I'm here to help you learn Google Tag Manager and Google Analytics. Join thousands of other digital marketers and digital analysts in this exciting journey. Read more
Analytics Mania
  • Google Tag Manager Courses
  • Google Tag Manager Recipes
  • Google Tag Manager Resources
  • Google Tag Manager Community
  • Login to courses
Follow Analytics Mania
  • Subscribe to newsletter
Recent Posts
  • Introduction to Google Tag Manager Server-side Tagging
  • 3 Ways to Pull Data from Data Layer with Google Tag Manager
  • Cannot See the Google Tag Manager Option in Google Ads Conversion?
Analytics Mania - Google Tag Manager and Google Analytics Blog | Privacy Policy
Manage Cookie Settings