Learn How to Implement User-ID Tracking

Learn How to Implement User-ID Tracking

Ever wondered how you can How to User-ID blog imagetrack visitors across devices? Have too much direct mobile traffic and wonder if this is the result of campaigns running on other devices?

There is a way! If you have read our previous post “User-IDs: Why & What” you would have learned that you can track a unique user across different platforms and to do so you must implement User-ID tracking.

For Google Analytics’ User-ID tracking to work you need to send a User-ID with every hit which means that the User-ID should be sent with every page/screen view, transaction and event you want to be associated with that user. It does not make much sense initially, as one would assume that User-ID would be set at the user level scope and not a hit level; however, this is not the case – User-ID does not work as a user-level custom dimension. This is necessary because, in some jurisdictions, privacy laws only allows you to track users that have explicitly authenticated and/or given you permission to track them only when they are logged in.

Items to ask for from your web developer

There are two different ways you can approach User-ID tracking implementation. Which way you would choose, should be based on technical feasibility, local privacy laws and your requirements to information about site users.

  1. Cookie Implementation – an easier and sometimes more technically feasible implementation from a technical standpoint, it requires developer to set a cookie with User-ID stored in it every-time user logs into your site
    • Pros:
      • Relatively easy and fast to implement from technical standpoint
      • You do not have to worry about User-ID not being present in the Data Layer – for example if you have 2 portals – gated and non-gated it might be very difficult/impossible to push User-ID into Data Layer on non-gated portion
      • You can track users that do not technically “log-in” but rather subscribe to your newsletter or contact you by setting a User-ID cookie at that time
    • Cons:
      • Cookies can be blocked by visitor’s browser
      • Negative image cookies got lately due to misuse by certain sites
      • If you are allowed/want to track logged-in experience only then you have to also ask developer to delete the cookie upon logout. Also, user might leave the site before cookie is deleted and the next non-logged in visit may pick-up the old cookie value and thus will skew your data/violate privacy laws
    • If you decide to go with this implementation, you should also ask developer to save unique User-IDentifier in a _gtmUID cookie (if you use different name for cookie take a note of that as we will be using this name later on in GTM)
      • You may consider extending cookie date to 6 months or beyond from the time of last login in order to capture all visits under the same User-ID, especially if your site does not require frequent log-ins in order to operate (and if you allowed/want to do so)
  2. Data Layer Implementation – requires User-ID to be present in Data Layer on every page where a user is logged in. Might be harder to implement but will ensure that there is no “misfires”
    • Pros:
      • Very robust solution if implemented correctly
      • Would not require you to do anything extra to stop tracking users once they log out
    • Cons:
      • If one page does not have User-ID available in Data Layer – it will break how User-ID behaviour is displayed to you in GA
      • Might be hard/impossible to use where people are not required to logged in every time they visit the site
      • Will require extra work if you want to track visitors beyond just the logged-in behaviour
    • If you decide to go with this implementation, you should also ask developer to do the following:
      • Add the following line of code to your page, just before the Google Tag Manager’s container snippet code:
        <script>dataLayer = [{'userID': 'YOURUSERID'}];</script>
         UID Code Snippet Example
      • If you are using a single page experience or a dynamic log-in functionality you should also ask for developer to execute the following line of JavaScript upon successful login:
        dataLayer.push('event': 'uidAvailable', 'uid': 'YOURUSERID');
      • Here and in the previous code snippet YOURUSERID is replaced with a unique User-IDentifier when it is available

Note that this User-ID should abide by Google’s requirements to PII no matter which implementation method you will decide to use.

Google Analytics Configuration

Once you have this implemented by a developer, the next step is configuring your GA to capture User-ID.

  1. In Google Analytics Admin section under “Property” -> “Tracking Info” -> “User-ID” you will have to read and agree to Google’s User-ID policy (see User-ID: Why & What for more details)
  2. After doing this and clicking next you will have to set up the User-ID and choose if Session Unification is something you would want to have “turned on”
    • Session Unification in GA essentially “stitches” all hits preceding the registration within that session to that User-ID. However, that does not mean that GA will go back in time and “stitch” other sessions by this user to the same User-ID, just the pre-registration hits for the current session
  3. Next step would be to create a User-ID view to capture and unify all the User-ID information
    • Note that this view will only capture hits that are sent with the User-ID set (plus any Session Unification hits)
  4. Finally, before you move on to configuring tracking in GTM, you have to create a userId custom dimension:
    • User-ID in GA is not a dimension that you can use in any GA’s reports (pretty much like GA’s clientID)
    • You may want to be able to analyze information or upload additional data via custom dimensions based on different User-IDs
    • It would make sense to set this custom dimension at user level scope unless you are only allowed to track only logged-in session in which case you may have to set it to hit level scope
    • Once you press “Create” take a note of index for this custom dimension as you will use that later in GTM

Google Tag Manager Configuration

You are now ready to configure Google Tag Manager to capture User-IDs and pass it to GA (Way To Go!).

To do that you need to create one variable and adjust Google Analytics tag(s).

  1. Based on which User-ID implementation method you picked you have to create one of the following:
    • Cookie Implementation – Create a new 1st-Party Cookie Variable that will read the User-ID value from a cookie:
    • Data Layer Implementation – Create a new Data Layer Variable that will read the User-ID value from Data Layer:
      • Name it userID
      • Set Data Layer Variable Name field to userID
      • Data Layer UserID variable
  2. Adjust your GA Tag(s):
    • GA_config
    • Note that you need to adjust every tag sending data to a specific GA property for this to work (Event, transaction, virtual page-views etc.)
    • Please note that I assumed that you have your userID saved in a custom dimension with index of “1”. You may have to adjust it (you can double check GA’s custom dimensions to confirm this)

3. Test to make sure it works as you expect it to

4. Publish! You are now tracking User-ID.

Watch for our upcoming post which will cover some of the more advanced configurations we listed last month in “User-ID: Why & What”.

We’d love to hear our your implementation went…and how you are using UserIDs!

By |2019-05-17T11:57:15-04:00July 13th, 2015|20 Comments


  1. Olgierd 2016-05-06 at 05:37 - Reply

    Hi Max,

    Great article. In my opinion the best article about this particular topic in the entire web – it answered questions that I had but couldn’t have found answers anywhere else. However I noticed possible contradiction in this article – in one of the first paragraphs of the article you write “User-ID does not work as a user-level custom dimension” and few paragraphs later you include screen of creating userID custom dimension where it’s clearly visible that you chose user-scope.

    Could you be so kind and clarify that?

    One more question – would you set field “&uid” in GA tag that sends only non-interactive events?

    • Max Bondarenko 2016-05-06 at 08:25 - Reply

      Hello Olgierd,

      Thank you!

      As for your questions, UserID has to be set with every hit sent to GA in order for GA to combine those hits in UserID unified view. This means that if you want to see a pageview or an event (both interactive and non-interactive) in the UserID view – you have to set “&uid” field on it.

      Effectively on GA side “&uid” field maps to a hit-level dimension (let’s call it “uid”). The problem here is that this “uid” dimension was not available in any reports in GA at the time when I was writing this post. And even now, it is only available in the new “User Explorer” report and is not accessible outside of that report. That is why I had to create “userId” custom dimension. The reason I decided to set “userId” to user level scope instead of hit level as per actual GA’s “uid” is because it made more sense to me due to the following:

      • It is a dimension describing a user not a hit or a session
      • If there were an issue on the client side and on a particular hit there was no UserID available – the hit will still be associated with that user in at least my custom reports due to how user scope custom dimensions work

      Hope this answers your questions!

      • Olgierd 2016-05-06 at 11:03 - Reply

        Hi Max,

        Thank you for your thorough answer :). I didn’t know about existence of hit-level GA-specific “uid”. In my case userID is assigned only for the duration of session so I thought that user-scope custom dimension wouldn’t be much of use. Do you think it’s justified reasoning or should I switch to user-scope?

        Also I have one last question that I couldn’t find anywhere else (even GA forum):

        Do you think that userID view with Session Unification enabled would show the same data as normal view with session-scoped custom dimension getting data from “&uid” variable? In both cases “&uid” variable is “undefined” once user logs out so data is not getting sent to GA.

        What do you think?

        • Max Bondarenko 2016-05-11 at 14:30 - Reply

          Hi Olgierd,

          The way you would define userID custom dimension would solely depend on your analysis needs. If you want to replicate “uid” behaviour then you may want too set it to hit-level. If you are interested in tracking only signed-in(more or less – see thenote below) sessions (and if you are in Europe – you may be required to) then using session level dimension makes sense. If you want to see complete user experience across multiple sessions then you may consider using user level scope.

          The session unified view will show data that is close to non-unified view with session-scoped custom dimension, but might have some variation due to how session unification works. If you stop sending userId after person logs out – then remainder of that session will not be displayed in the session unified view; however, your view that is based on session level dimension will include the rest of the user session. See more on how session unified view works here

  2. Nik 2016-07-17 at 12:57 - Reply

    Hi Max. Thanks for the article. Just great 🙂

    I have a question. What you mean when you say “If you are using a single page experience or a dynamic log-in functionality you should also ask for developer to execute the following line of JavaScript upon successful login…”

    Why a single page website should receive a different setup ?
    And what you mean with dynamic log.in?

    Thanks a lot!

    • Max Bondarenko 2016-07-18 at 13:17 - Reply

      Hi Nik,

      Thank you for your question!

      When I mentioned dynamic login I meant a login process that involves some sort of AJAX where person can login into their account without going to a different page or reloading an existing page. Quite often this “dynamic login” feature is used in single-page websites and web-apps.

      When a visitor logs into their account without reloading a page you need to tell Google Tag Manager that a person have logged in and that GTM should pass this information to GA. That is why the setup here might be different.

      Hope this answers your questions.

  3. Sunayana Goyale 2017-05-02 at 12:23 - Reply

    Hi Max,

    Thanks for the article. I’ve followed the instructions and configured User ID for my website, which is single page application. But, I’m not able to see complete set of user ids in user id view report. Either one or two users with their user ids are being tracked by GA. What could be the reason behind this lag?

    And, do I need to place the script (that you’ve mentioned) before GTM script in the source code? Note – mine is single page application.

    I’ve checked the configurations in GA & GTM interfaces as well, they seem to be fine, not sure though.

    Can you please guide me to get proper data in GA for user id tracking?

    • Max Bondarenko 2017-05-29 at 10:51 - Reply

      Hello Sunayana,

      You have to make User ID available in Data Layer. It doesn’t have to be added before GTM container but has to be made available when person is logged in and then sent with every hit. If you do not send User ID to GA with every then User ID view might not stitch sessions correctly.

  4. Karan 2017-05-04 at 01:47 - Reply

    Looks good but do I need to set the scope as Hit or User in Custom Dimensions section of GA? I am not able to track the data in User ID view. Followed all the instructions of Data Layer approach from this article. Pls help.

    • Max Bondarenko 2017-05-29 at 11:22 - Reply

      Hello Karan,

      By the sound of it – it might be that you are not sending User ID to GA with every hit. If User ID is not sent with every hit then you need to fix that first. Perhaps you can set the User ID Custom Dimensions to hit level scope at this time to see where (i.e. what page views and events) you do capture User ID to troubleshoot it.

  5. Ateeq Ahmad 2017-07-06 at 14:05 - Reply

    Hello Sir,
    Such a good explanation for this. I do appreciate it. However it doesn’t work for me. I am seeing the userID being passed through the data layer but seeing no traffic in the Real-time reporting section.

    I tested custom dimension both at the user and hit level. The only difference is that I had to name my custom dimension as userID instead of your userId. I tested within GTM preview and the tag was being generated correctly. What else could be going wrong?

    • Max Bondarenko 2017-07-17 at 10:34 - Reply

      Hello Ateeq,

      Just to clarify do you see event in GA real time or no? Also when you said you used you are using userID instead of userId – do you refer to The GTM variable name or what you use as a “Field Name” under fields to set?


  6. Petronella 2018-12-18 at 22:15 - Reply

    Hello max, this tutorial really helpful and I already followed it. I want to track user ID using layer data with google tag manager. When I preview on my website, the custom dimension result is right. But when I see on my google analytics with custom report, there’s nothing in there. Any ideas why that possible happen? thankyou

    • Marc Soares 2018-12-19 at 14:01 - Reply

      Hi Petronella,

      Glad you found our tutorial helpful. It is difficult for us to advise on what the problem may be without seeing your implementation.

      If you are retrieving the user ID value from the data layer, you should ensure that the variable is properly configured in your GA tag. Step 2 in the Google Tag Manager Configuration section above shows how the userId field and the custom dimension index should be set in the GA tag.

      Once your tag configuration is correct, I suggest using the GTM preview and debug panel to ensure that the user ID value is populated at the time the GA tag fires. If the user ID variable is undefined when the GA tag fires, the user ID value will not be sent to GA.

      Hope that helps!

      • Petronella 2018-12-19 at 20:28 - Reply

        Hii, I really appreciate that you answe my question.

        Thats why I am so confuse,
        – I have set custom dimension in GA with the same index on GA tag
        – I have previewed debug panel and I’m sure that custom dimension set the right user ID

        Is there any settings in GA that I should consider?
        For this case, is custom dimension is not retroactive? But, it’s been two days, and still nothing happen in GA custom report

        Sorry, if I asking you a lot of question, cause I learning with myself, so thank you very much 😀

        • Marc Soares 2018-12-20 at 15:15 - Reply

          Custom dimensions are not retroactive. GA will only start collecting the custom dimension values when you begin sending them.

          To avoid any impact your GA settings may have, I suggest looking at the data in an unfiltered view. Create a custom report with only your user ID custom dimension and the sessions metric.

  7. Hanna 2019-10-14 at 14:54 - Reply

    Can I do this without tag manager

  8. santosh mandal 2021-03-24 at 02:00 - Reply

    Hii max,
    I’m not getting the any data in userId views and when I switches my view to all website data so then only I got the data of users.

    • Nicole Harris 2021-04-06 at 10:31 - Reply

      Hi Santosh, thank you for your question! If you are not seeing any data in the User ID view there may be an error in how you set up User ID. However, we would need further information to pin point where the issue is. Setting up User ID does not impact the non-User ID views which is why you are still seeing data in your All Website Data view.

Leave A Comment