Google Analytics Email Tracking, Part 2


In part 1 of this series, I showed you how to use Universal Analytics and the Measurement Protocol to track whether or not someone opened your email.

Now we’re going to kick it up a notch use email to tag visitors with a unique ID. This will let you track visitors to your site across devices, like below:

Email tracking in Google Analytics with MailChimp


We’ll continue from where we left off after the last post, so I’ll assume you’re already using Universal Analytics, and you have a custom metric set up to keep track of email opens. We’ll continue to use MailChimp to walk you through setting this up, but you should be able to apply these steps to whatever email marketing platform you’re using.

Step 1:

In step 1 of the last post, you created a custom metric in the Google Analytics admin interface called Email Opens to track the number of times an email was opened. This time, you’ll create a new custom dimension called Visitor ID to keep track of individual users.

Log in to Google Analytics and go to the Admin section. Select your account and web property, and click on Custom Definitions under the Web Property column. Then click on Custom Dimensions.

Custom Dimensions

In the next window, click on the New Custom Dimension button, and give your custom dimension a name (I recommend Visitor ID) and set the scope to User. Also, make sure the Active check box is checked.

Custom Dimension

Step 2:

Now that you’ve set up your custom dimension, it’s time to start populating it. In our example, we’re going to do that through email marketing. When someone opens your email, it will show up in Google Analytics as an email open from visitor ID 12345 (or whatever their ID is). And when they click on a link in the email, it will show up as a visit from that same visitor ID.

To do this in MailChimp, there’s a feature that we’ll take advantage of called Ecommerce 360 link tracking. You’ll find this in the Setup phase when you’re creating an email campaign – check the box for Ecommerce 360 link tracking:

MailChimp setup

MailChimp Ecommerce 360

So, what is Ecommerce 360? Basically, it makes it possible to track visitors from your email campaigns, capture transaction information, and pass it back to MailChimp.

But that’s not why we’re using it. We’re using it because when you have it enabled and someone clicks on one of your email links, it adds a couple of parameters to the end of your URL. Specifically, these are the parameters:



The mc_cid parameter is the internal MailChimp campaign ID and the mc_eid parameter is the unique, MailChimp-generated ID for the list member.

In other words, MailChimp is giving you the unique ID to use in your Visitor ID dimension!

Step 3:

To get that ID stored in your Visitor ID custom dimension, you’ll need a tiny bit of script on your page to check for that value in the URL and capture it. If you look at the source code on this site, you’ll see our Universal Analytics code has been updated to include this extra code (lines 9-17):

Step 4:

With the script above, plus the Ecommerce 360 option in MailChimp, you’ll now be capturing the user ID of visitors who click on the links in your emails, but remember, we also want to do that if they open the email (without clicking a link).

To do that, we’re going to modify the code from step 6 in the previous post. This is where we’re placing our “fake” image at the bottom of the email that sends the data to Google Analytics:

The only difference from the previous post (the code above) is that we’re now also going to add the unique ID to the custom dimension. We can do that as follows:

The payoff

OK, so I admit that you’ll have to roll up your sleeves and get your hands a little dirty with some code. But your efforts will be rewarded with large sums of money and glory.

You’ll now be able to see the following scenario playing out in your data:

Visitor ID 12345 (which you can match back to John Q. Smith in MailChimp) opened your email on his phone on a Monday. Then he opened the same email from his computer on Tuesday and clicked the link to go to your site, where he browse around but didn’t convert. Then he came back to your site on Thursday and made a purchase (or signed up, subscribed, etc.).

Cross device nirvana!

Jim Gianoglio is a Manager for the Analytics & Insight department. He works with implementation, analysis and training of Google Analytics and Google Tag Manager. Before focusing on analytics, he led the SEO campaigns of Fortune 500 companies in the insurance, retail and CPG industries. Things you didn’t know about Jim: he’s biked from Pittsburgh to Washington DC in 41 hours, roasts coffee beans and has done voiceovers for TV commercials.

  • Thanks for showing this end to end. It really helped me understand the glory of analytics.js!

    One question: If the the recipient’s email client does not automatically ‘display images,’ will this method still work?


  • @Trevor –

    No, this only works if their email client displays images (either automatically or if they click the link to show images like in Gmail).


  • Thank you so much Jim. You have no idea how long I’ve been looking for a clear solution to this problem! I’ll be summarizing the benefits of this type of tracking in an upcoming blog post and linking to this post. Thanks again for the great info.

  • Jason

    Jim –

    This is great! I’ve completed Pat 1, but have a few questions on this second part when it comes to updating the Universal Analytics code:

    – We don’t have lines 7 or 19 (in addition to 9-17). Do we add those two lines as well?

    – With our e-mail provider we will only be receiving the equivalent of “mc_eid”. That would be sufficient, right?

    – Was wondering if you could break out what each of the new code sections mean (similar to what you did for the email script in Part 1). I’m trying to figure out if I need to change any part other than the “var mcId = hash.match(‘mc_eid=(.*)’);”

    – One final question. Would we need to update the “Exclude URL Query Parameters” in the Profile settings to exclude “mc_eid”? I would think so because otherwise we would get a separate page view for each unique visitor.

    Again, this series is incredibly helpful! All the development is greek to me, but this is very easy to follow!

    • @Jake – I’m glad I could help! Thanks for the feedback.

      @Jason – you may not need lines 7 or 19. The reason that existed in our code was because the “ga” variable name was already being used by an existing object on the page, so I just used jQuery to localize the ga variable for Universal Analytics. I’ve since updated it to rename it gaTracker (you can read about the details of how to do this in the developer documentation). So instead of:

      ga(‘send’, ‘pageview’);

      we’re now using:

      gaTracker(‘send’, ‘pageview’);

      for example.

      As for the “mc_eid” equivalent parameter, yes – as long as you get that, you don’t need anything else (like the mc_cid parameter).

      I’ll see what I can do about clarifying what that script does – more information is better, right? Also – excellent point about excluding the query parameters in your profile settings. You are correct – you’ll want to exclude the mc_eid and mc_cid (or whatever parameters your email service provides) or else you’ll see the same page showing up in your content reports under many different URLs.

  • Ylva

    Hi Jim!

    Thanks for this post! I’m developing a project in iOS for a client, and have included the use of a Custom Dimension in the way you describe here – to track a user id (an alphanumeric unique id in our case). In my case the interest in the id is to be able to cross the analytics with data warehouse info. A question arose from the client, that I do not seem to find an answer to in the Google Analytics documentation or anywhere else: Is there any limit to how many different values a Custom Dimension can take? The number of individual users in this application could be quite big I’m assuming, so the question is interesting to not bump into trouble later on. Thanks again and I’m hoping that your expertise could give me the answer.. 🙂

    • @Ylva –

      There is no limit to how many different values you can pass to a custom dimension, but there is a limit to how many will be displayed in the reports. For the free version of GA it’s 50,000 rows of data (values) per day, 75,000 for GA Premium.

      For example, if there are less than 50,000 unique user IDs per day, than you will see them all. But if you have more than 50,000 unique IDs for a given day (let’s say you have 60,000), than GA will show you the first 50,000, and for unique IDs 50,001-60,000, they will be aggregated into a single row of data labeled “(other)”. You may have seen this before – most commonly in the content reports.

      Also, if this is for a mobile app, you’ll want to use the Google Analytics SDK and set the custom dimensions that way. Check out the developer documentaion for custom dimensions and metrics for the iOS SDK for the details.

      Hope that helps – good luck with your app!

  • Great article, thank you. However I’m afraid the visits metric is not tracked correctly. I suppose that every email open is counted as a Visit too, isn’t it.
    That means if particular visitor ID has one Email open and one Visit, it actually means the guy did open the email, but didn’t visit the page. Am I right.

    Why do I think that? Because I implemented the openrate tracking (in every email there is unique img request with the visitor id) but I didn’t append the visitor id in the links. So when somebody clicks on a link in my newsletter, my website and google analytics doesn’t know it is a visit from that newsletter, from that visitor id.
    And still in my reports there are visits being tracked exactly like in your report.
    And there is no Visitor with an Email open and without a visit. That is strange isn’t? I mean there must at least somebody who opens the email and does’t click , right?

    Am I right? Is the visit metric inflated with every email open?

    Now we can just create a new custom metric (email clicks) and compare with that instead of with visits, right?

    Thanks in advance for any feedback

  • Angel

    This was a super useful post. Thanks for putting it up.

    However, I have an issue with the tracking. Maybe you’ve found a way around it.
    #1) This is tracking non-unique “Email Opens”. That poses a problem because when you are using the opens in a funnel to understand Lead Gen you see that some people open the emails several times and this makes tracking real completion of a funnel through to Open not possible. Have you found a way to track unique opens only? i.e. with the same uniqueID

    #2) Aweber doesn’t have a unique identifier like MailChimp (or at least I have been unable to find in their documentation – am contacting their support about it)

  • Troels

    Looks like you have a typo in the Javascript snippet. mcID and mcId would be two different variables, so you should probably change that if-statement to if (mcId)

    • @Troels – thanks for catching that! I just updated to make the change.

  • Is it possible to see what content the visitor viewed, including landing page + subsequent views?

  • @istrategist – if it’s a specific user you’re interested in, you can create an advanced segment for that Visitor ID and apply that to your content reports. For a higher level view, you could create a custom report that would show Visitor ID and landing page as the dimensions, along with the appropriate metrics.

  • Thank you for this great article.

    I noticed something, you use both one event and one custom metric to register email openings. Why don’t you use only the custom metric like a meter ?

  • @Florent –

    One of the required parameters of the Measurement Protocol is the hit type (t=event). You can’t send a hit with just a metric – it has to also have the hit type. The hit type parameter accepts one of the following values: pageview, event, transaction, item, social, exception, or timing.

    So you could use a hit type of ‘pageview,’ but then that would artificially inflate your pageview numbers. Events make the most sense, plus you can add additional info using the event category, action, label and value.

  • You should add a link to this part 2 at the end of part 1 🙂

    When I finished reading part 1 it took me a few minutes to find this one. Ended up getting lucky with a site: search of your domain.

  • @Phillip –

    Thank you for pointing that out! I just added links at the top and bottom of the first post to point to this one.


  • I actually just found that doing this violates Google’s privacy principles…

    “4. Don’t send personally identifiable information.

    Google Analytics customers are prohibited from sending personally identifiable information (PII) in a campaign tracking parameter. PII includes any data that can be used by Google to identify an individual, including (but not limited to) names, email addresses, or billing information. Learn more about the Google Analytics privacy principles.”

    • @Phillip –

      The important element of that part of the ToS is “… data that can be used by Google …” (emphasis mine). Google doesn’t have access to your MailChimp account, so they are unable to identify an individual based on that ID. It’s similar to transaction ID on the ecommerce side. For example, I can clearly identify individuals based on a transaction ID, because I have access to my site’s ecommerce database. Google, on the other hand, has no ability to take a transaction ID and match that up in any way to an individual.

  • You’re right… I re-read it right after I submit my comment and realized that it says what you emphasized. I didn’t have the ability to edit my comment though 🙁

  • Hello Jim Gianoglio.
    I just setup everything like you described in you two posts. It’s a little hard to test because events are not processed in real time by Google. I have one question. How did you setup your table for viewing data with VisitorID, Email opens and Visits? Like the first picture in this post.

  • Jim, I thought you might be interested in my “PII Viewer for Google Analytics” Chrome extension:

    It allows you to map real user names and other PII onto the Google Analytics interface from locally stored data. It should help analysts figure out “who is doing what” much more easily .

    Also, Google has confirmed that it complies with section 7 of the ToS.

  • @David – I like the looks of your tool. Can you provide some instructions on using it (a link to a post on your site would be good)?

    I’m guessing you have to name your custom dimensions “Custom User ID” and upload a CSV file to the plugin folder – is that about right?

  • Jim, here’s video of an early incarnation

    I’ll update you with a new video soon.

    • Well done David – I like this. However, the User ID that gets passed to GA will not be an available dimension in GA. But you can store the same ID as a custom dimension and get the same functionality out of your tool.

      Thanks for this Chrome extension!

  • @Primoz –

    Events should show up in the real time reports, but I have noticed some inconsistencies there.

    As for the report in the first image of this post, it’s a Custom Report. Just choose the custom dimension you set up (in this case, Visitor ID) as the dimension for the reports, and the custom metric (Email Opens) and visits (now called sessions)as your metrics. Then you can choose Device Category as a secondary dimension. The image uses the dimension “Mobile (Including Tablet)” as the secondary dimension, but Device Category is probably better and will show “desktop”, “mobile”, and “tablet” as possible values instead of just “yes” or “no”.

  • @Jim

    Thank you for clarification I was confused because the recent “visits” and “sessions” change.

  • David

    I’m pretty sure this is against Google Analytics terms of service which states that you can’t collect individually indentifiable information in GA. Right?

  • @David – there is no PII being stored. Just a random unique string that YOU are able to use to identify your users. Google has no way of tying that ID to an individual person.

  • Quentin

    Thanks for this article. it is exactly what I needed.
    One thing I can’t figure out is how to view the mc_eid in mail chimp.


  • First of all congratulations for this fantastic post.

    I’d like to find an answer for the same question that Peter did. Tracking email opens inflates the number of visits (sessions) in Google Analytics, and so reduce the other KPI’s as PageViews/session, etc

    Jim or anyone found a solution?

    Thanks in advance

  • Thanks for the post!

    Can the extra lines of code added to the Universal Analytics code somehow be added through Google Tag Manager? I’m using GTM and I’m not sure how I can implement the above.


Contact Us.

Follow Us



We'll get back to you
in ONE business day.
Our Locations
THE FOUNDRY [map] LunaMetrics

24 S. 18th Street
Suite 100

Pittsburgh, PA 15203


4115 N. Ravenswood
Suite 101
Chicago, IL 60613


2100 Manchester Rd.
Building C, Suite 1750
Wheaton, IL 60187