16 Dec 2015
Analytics custom dimensions in Google Tag Manager
Reading time: 15 mins.

GUIDE: Analytics custom dimensions in Google Tag Manager



As we know, Google Analytics includes a set of predefined dimensions and metrics. The tables in most Google Analytics reports organize dimension values into rows, and metrics into columns.

So, every Report consists of two parts: metrics and dimensions. Metrics contain quantitative data (visits, pageviews, conversions…). Conversely, dimensions contain qualitative data about users, sessions, hits… (Traffic source, keyword, type of visitor).  

Look at the chart below. Whereas dimensions tend to be located in the vertical axis, metrics tend to be located in the horizontal axis.   

Google Analytics Dimensions Metrics

In most reports, we can add a secondary dimension in reports:

Analytics table two dimensions

Images source and more information:  https://support.google.com/analytics/answer/1033861?hl=en

⇑ Content map (back to top) ⇑


It is often necessary to collect additional data (not collected by Google Analytics by default) of every session, interaction, transaction, etc. by sending extra custom variables. Some examples:

  • Custom dimensions for blogs: User ID, category, author, tag, etc.
  • Custom dimensions for E-commerce sites: User ID, site language, product category, product details, stock data, etc.

The first step in custom variable configuration is to define Custom metrics and parameters/dimensions in Google Analytics. Therefore, go to Property settings in your Admin tab and select what you want to configure. In this case: Custom Definitions > Custom Dimensions. 

Analytics property level

Analytics admin create custom dimensions

Specify dimension name and scope to create the custom dimension. Read this article –kaushik.net/avinash/hits-sessions-metrics-dimensions-web-analytics and the following section to gain a better understanding of dimension scope.

⇑ Content map (back to top) ⇑



Dimension scope is related to how often dimension values are sent to Google Analytics.  

These are three dimension scope levels:

Analytics custom dimensions index


As shown in the table above, every Analytics Custom dimension is assigned an unique index and a scope level. Dimension and metric scope are essential to collect data correctly and logically for our reports in response to queries. Dashboards, widgets and custom reports, for example, must be therefore created carefully.

Analytics Avinash level scope dimensions metrics
Image source: kaushik.net/avinash/hits-sessions-metrics-dimensions-web-analytics



It is not convenient to combine dimensions and metrics with different scopes. Hit-level dimensions such as Page should not be queried with Session-level metrics such as Goal Conversion Rate. The data in the resulting report will be wrong. We should use session-level dimensions like Landing Page instead, with session-level metrics like Goal Conversion Rate –https://support.google.com/analytics/answer/2709828?hl=en-.

In order to know which dimensions can be combined with which metrics you can use this utility at the Dimensions & Metrics Explorer:

Analytics dimensions metrics reference

Image source: Dimensions & Metrics Explorer

Google Analytics dimensions metrics reference

The dimension scope (hit-level, session-level and user-level) affects the dimension value. For example:

  • Hit-level scope: it applies different values for different interactions or hits within a session. The values are sent to Google Analytics with any interaction the user has with the website. Mainly, when the browser reloads the page (i.e.pageviews), but also when an event or another hit type is tracked (social hits, transactions). Hit-Level dimensions examples: Page, Title, Product category…

HIT-Level Scope - Google Analytics Custom Dimension

Image source: Custom dimensions and metrics (by Google)

  • Session-level scope: it applies and sends an unique value per each session.  The value from the last hit will prevail over any value from any hit registered previously during the same session. Session-level dimensions examples: Source, Medium, Browser, Device… Remember: only a value per session, even if there are several interactions in which we send different values. For instance, if a user navigates in several languages during a session, Google Analytics will only collect the last one.

USER!!-Level Scope - Google Analytics Custom Dimension

Image source: Custom dimensions and metrics (by Google)


  • User-level scope: it applies and sends an unique value for ALL the sessions of an unique user.  For instance, City: Granada.  When different values are sent by  different hits during a session, the last user-level dimension hit will prevail. If a user with a defined user-level dimension (City) returns and visits the site regularly, his following sessions will include the same custom dimension value, without being required to send it again. User-level dimensions examples: Gender, Age, Registered/Not registered… they depend on cookies that identify the user. They send an unique value to Google Analytics for every user/cookie.  Their value does not change along sessions, unless the user himself changes this setting.

USER-Level Scope - Google Analytics Custom Dimension

Image source: Custom dimensions and scopes (by Google)


⇑ Content map (Back to top) ⇑



Once a dimension is defined in Google Analytics, an index is assigned to it. A code to implement it will then show up.

Custom dimensions Google Analytics

Luckily, we DON’T need to edit the website code at all. Instead, we configure it as a Tag manager field in the Google Analytics tag.

Custom dimensions Google Analytics code

In More Settings fill the Custom Dimensions section so that the GTM  Index matches the Analytics Index. Dimensions in GTM have their own configuration section so far.

Custom dimensions tag manager setting

In Index fill the Dimension number like you did in Google Analytics. We used index 1 and 2 to name them in Google Analytics. Do the same in Tag Manager.


Custom dimensions category author

Note: these are two Hit-level dimensions, since their value can vary depending on the visited URL-pageview in this case.

⇑ Content map (Back to top) ⇑



There are two important questions about about dimension value and configuration:

1. How do we populate Google Analytics with Dimensions data from GTM? Which Dimension value configuration is required in this case?

Dimension value should be filled with data we want to populate Google Analytics.

For instance, with regard to post author and category custom dimensions, we will need dynamic variables to collect data from source code. And we will send them this data to GTM via dataLayer.

There are different ways of populating data depending on where we collect it from (dataLayer, DOM, etc.). However, it would be a dynamic value in the majority of the cases.

So, we will always use GTM variables to fill Dimension value. This variable can be dataLayer, Custom JavaScript, Lookup Table, URL, etc. Even if the dimension value is static, it is highly recommended to use a Constant variable.

2. Should we configure dimension data in every Universal Analytics tag? Is it required with every hit type?

It is possible to send dimensions in every available hit type: Page view, Event, Transaction, Social, etc. When and where we configure custom dimensions will vary according to its meaning. Some examples:

  • USER ID – apart from its default setting (Field to set: userId), we can configure it as a custom dimension. In this case it would be very useful to send it with every hit type: event, pageview, social, transaction… in order to have User ID available in as many GA Reports as possible, by using secondary dimension utility.
  • Product Category – it doesn’t make any sense to send it with every hit to Google Analytics. Instead, we will normally send product category only in Event/Pageview tags that refers to the product and category. Anyway, if we configure Product Category Dimension in all the tags, GA tracking will still work.

The amount of tags in which we configure custom dimensions depends on dimension scope. For instance, it is possible than some session/user scope dimensions could be only populated in a single point, page or event. And so, we should send data just in the appropriate tag/s.

For example: imagine we wished to count the cumulative spending per user. We could create a new metric and send just the order value pushed into E-commerce dataLayer (like an additional custom metric).

⇑ Content map (Back to top) ⇑



Let’s move on to the next step: sending dimension data.


  $cats = get_the_category();
  $cat_name = $cats[0]->name;

(Next, use this code snippet to push data into dataLayer).

window.dataLayer = window.dataLayer || [];
'section': '<php echo $cat_name; ?>'

We insert both code snippets in header.php wordpress file, just after the <body> opening tag and before Tag Manager container code. We can test it with Google Tag Assistant plugin:

Custom dimensions datalayer tag assistant

The next step is to create dataLayer variable in Tag Manager, in order to collect data from the code above:

Category section datalayer variable GTM

Configure as seen before at GTM Universal Analytics tag:

More Options> Custom Dimensions> Index: N and value: {{Category}}.


If we want to collect user ID, we can use the following dataLayer code snippet.

window.dataLayer = window.dataLayer || [];
'userId': '<?= get_current_user_id(); ?>'

NOTE: Do not mistake sending User ID to GTM via Data Layer for sending hit data to Google Analytics. It is a previous step.   

It is essential to create another GTM variable to collect dataLayer value:

User id analytics datalayer variable GTM

Finally, configure {{User Id}} variable as a custom Analytics variable.

User ID analytics custom dimension GTM

Last but not least, don’t mistake sending UserId as custom dimension for setting up userId parameter in order to have GA multi-device view and specific reports.


Imagine we wanted to configure reports and preview with ID user in Analytics: {{userId}} variable not only will be send in Custom Dimensions but also in Fields to set (field name: userId). Let’s see Google Tag Manager settings for this option.    

User ID Tag Manager field to set setting


⇑ Content map (Back to top) ⇑



  1. Extra dimensions and metrics are always possible at dataLayer

In many projects, it is a good idea to create a generic custom dimension to be used as a wildcard when necessary. I.e. when standard available event parameters (category, action, label, value) are filled with useful information but you have some extra data to send, it could be useful to have an “Additional Info” custom dimension to be used as a catch-all. For example, event error:

  • Category: ERROR
  • Action: ERROR Form: Contact
  • Label: ERROR Field: {{Form field ID}}
  • Custom dimension: ERROR Text: {{Error message}}

It is very important to notice that custom metric and dimensions can be configured at ANY Google Analytics’ GTM tag. And the same occurs with dataLayer. It is possible to add additional custom metrics or dimensions to any dataLayer we code, even to Enhanced Ecommerce dataLayer. It is a powerful way to complete and improve Google Analytics data.

  1. Every dataLayer with an event

Another good idea is sending transaction data always with a custom event push in the same dataLayer. It can be used to send at the same event custom dimensions or metrics – if required –. And, last but not least, it is convenient to have the easiest trigger definition and also the most reliable one for Ecommerce transactions. For example, Ecommerce dataLayer with additional custom event, dimension and metric:

window.dataLayer = window.dataLayer || [];
 'dimension5':'custom dimension data',  'metric5':'custom metric data', 'ecommerce':{  'currencyCode':'EUR',                       // Local currency is optional.  'impressions':[      {        'name':'Triblend Android T-Shirt',       // Name or ID is required.        'id':'12345',        'price':'15.25',        'brand':'Google',        'category':'Apparel',        'variant':'Gray',        'list':'Search Results',        'position':1      },      {        'name':'Donut Friday Scented T-Shirt',        'id':'67890',        'price':'33.75',        'brand':'Google',        'category':'Apparel',        'variant':'Black',        'list':'Search Results',        'position':2      }]   } }); </script>


3. Think different: Imagine and take advantage of all available options.

Thanks to GTM, there are some almost automatic custom dimensions that we easily can set up and send to Google Analytics. They are based on predefined GTM Variables. Let’s see some examples:

  • Page URL, Page URL with Fragment, Page URL with/without (UTM) Queries, Page URL cleaned up (without protocol, www, queries, etc.) to get simplified GA Page values.
  • Referrer: In most cases, full browser referrer value is better than GA Source and Medium dimension data. We can easily collect it using the {{Referrer}} GTM variable. And, sometimes, referrer is useful to discover bad redirects – not 301 – and non-direct traffic classified as (direct) / (none) in Google Analytics.
  • URL Queries: it is possible to populate Google Analytics with any query parameter we could need. In order to do this we will create new {{Page URL Query}} variables, one for each query we wish to collect, for example to get data from that typical internal advanced search motors which use URL queries like this: domain.com/?search=keyword&searchCategory=categoryABC&searchType=advanced&searchLocation=leftbar
  • DOM Element: some HTML elements may change their text or some attribute value according to different website versions/access time/time zone/etc. We can collect this different texts/values with {{DOM Element variables}} to create an Analytics website change log and analyze results for different website versions.
  • Some metatag value…

With GTM you can get almost everything you can imagine, so just think! 😉

  1. With Universal Analytics version and Content Grouping apparition, there is a business data type that we used to populate GA with before using Custom Dimensions and now is a better option to populate using Content Groups. In the case of information to rank / sort pages by business type or proposal is  recommended to use Content Groups instead of Custom Dimensions. Some examples are: product categories, subcategories, language website version, page type: product detail/ listing/home/check out process/etc. … The reason is that Content Grouping offers more options thanks to its own dimensions and metrics that are useful to analyze groups flow, landing group, exit group, unique group pageviews…

⇑ Content map (Back to top) ⇑


Nowadays, every analyst has suffered from fake referrals and other Google Analytics Spam types.

First, spam robots made fake -real- visits, until they were excluded by GA filters by referral / source lists. Second, they just populate GA with data using Analytics Measurement Protocol (without accessing your website).

But what on hell is this…? To summarize, Measurement Protocol consists on remotely sending data to a GA property, making HTTP requests to send user interaction data directly to Google Analytics servers. It is useful to tie online to offline behavior, to track new enviroments (like call centers data, offline data), etc. By  HTTP requests (URL with a lot of parameters, including the Google Analytics UA-number),  you can populate GA with data, but you can populate your GA property or almost any other GA property… That’s the problem…

Some moths ago I tought: “Why there is not a password to these HTTP requests? I don’t want everyone could send data to my GA properties… but only me.” And finally I found the answer on a blog post. It is possible to define a password 🙂

In this article, Iñaki Huerta gave me the key to avoid all these automatic hits that are sent by Analytics Measurement Protocol.

In order to do this, we will use an Analytics Custom Dimension and a Filter. We are going to explain the process here, doing it with Google Tag Manager:

1. Add the custom dimension in Google Analytics (in my case, index 13):

Anti spam filter

2. (Optional) Active {{Random Number}} predefined variable in GTM, just to do it a little bit more complex…

Random number Google Tag Manager

3. Create a constant variable in GTM, including the random number and some additional text:

GTM variable you shall not pass


*We can give the constant the value we prefer, please, remember that random number is just an option.

4. This is an essential step: Configure the custom dimension at EVERY GA TAG in GTM, filled in with the constant variable we have just created in the previous step. It is fundamental that we send the custom dimension with every hit (every GTM GA tag) as the rest of hits that don’t have the custom dimension will be excluded from the Google Analytics main views and reports when we create the filter in the last step.

Analytics anti-spam custom dimension5. Test, debug and publish GTM container.

6.Create the GA filter, first in our Test View. What we wish is to exclude every hit that was not sent by us. So, we will generate an “Include only” filter to only keep in the view those hits that bring our antispam custom dimension filled with the correct value. Of course, after testing the filter in the Test View, we will add this to all our relevant GA views:

Google Analytics antispam dimension filter

Filter Pattern depends on what the constant variable I’ve created before contains. It could be something 100% static without any problem, e.g. “myValue” in both fields (GTM custom dimension and GA filter).

The most important thing is that GA spammers, by default, will not know that you are using a custom dimension like a password mechanism to collect only the correct-real hits. So, you gain security adding this extra control to your data.

 ⇑ Content map (Back to top) ⇑