1. Home
  2. Docs
  3. Tutorials
  4. Tutorial: Integrating JavaScript tags with Google Tag Manager

Tutorial: Integrating JavaScript tags with Google Tag Manager

This setup guide is divided into three sections:

  1. Setting up Google Tag Manager (GTM)
  2. Integrating Snowplow JavaScript tracking tags with Google Tag Manager
  3. Integrating Snowplow JavaScript tracking tags with enhanced ecommerce
  4. Next steps

If you have already setup Google Tag Manager on your website, you can proceed directly to section 2. However, we recommend at least skimming the section on setting up Google Tag Manager, as we’ve seen a number of companies implement this badly, with the end result that they cannot pass all the data they would like to Snowplow tags for analysis later.

1. Setting up Google Tag Manager (GTM)


There are six steps to setting up GTM to the point you can integrate Snowplow (or any other web analytics tool) with GTM:

  1. Create a Google Tag Manager account
  2. Integrate the container tag on your website
  3. Work out what data to pass to Google Tag Manager from your website, using the dataLayer
  4. Work out how to structure the data passed into dataLayer
  5. Integrate the dataLayer onto your website
  6. Create variables stored in the dataLayer in in the GTM UI

Typically, the steps people get wrong (or miss out alltogether) are steps 3-6. Getting them right is critical, however, because if you do not setup a robust mechanism for passing all the relevant data you want to report on in Snowplow (or any other web analytics program) into GTM, then GTM will not be able to pass that data into Snowplow, in turn. Either you will need to go back to your webmaster to add additional lines to your HTML / JavaScript to pass the missing data points later, or you’ll be forced to perform analysis without them. Managing the data pipeline between your website(s) and GTM is key.

1.1 Create a Google Tag Manager account

Creating a Google Tag Manager account is very simple. Log on to https://www.google.com/tagmanager/ and select the SIGN IN button. Once you have signed up, elect to create a New Account. Give the account a name. Then within it, create a Container and select your platform.

In general, you’ll only need to setup a single account, and most likely a single container for each domain you manage. However, that is not necessarily the case:

  1. A container is a single GTM tag that you will install on your web pages instead of the individual tags from different web analytics and other vendors. If you use a common tag setup across many domains, then you can use the same container across multiple domains, rather than create a container for each domain. This might save administrative time in GTM, because you can then add and manage tags across all the domains in one go. (It is straightforward to add tags for a single domain within a multi-domain container setup, and to distinguish data collected from each domain, so there really is no disadvantage in using a single container across multiple domains.)
  2. An account is a grouping of containers for administrative purposes. In general, one account is all you would need. If you work with different teams to manage different containers, then it makes sense to group the containers used by each team into a single account, with each team member being granted access to the account.

1.2 Integrating the container tag on your website

Once you have created a container, Google will provide you with the actual container tag. You will need to integrate this on every web page on your website(s), in place of any tags that are currently directly integrated on those web pages. (These will need to be migrated into GTM.)

The embed code needs to be inserted on your web pages immediately after the opening <body> tag.

1.3 Work out what data to pass to Google Tag Manager from your website, using the dataLayer

The dataLayer is a JSON that contains name value pairs of data points you wish to pass from your website into GTM. (And GTM can then, in turn, pass on to any tags that are managed in GTM, including Snowplow tags.)

Working out what data should be passed into the dataLayer is critical to ensuring that your GTM installation lasts. Getting it right, however, is not trivial. On the one hand, you need to be as comprehensive as possible: you need to identify every data point you might want to interrogate in your web analytics and make sure it is passed into the dataLayer. Otherwise it will not be possible to pass it on to Snowplow to use in analytics later.

On the other hand, you don’t want to swamp GTM with lots of data that is never used: either because it is not passed onto any of the tags GTM manages, or because those points are never used as part of Snowplow analyses.

We recommend erring on the side of comprehensiveness: the cost of passing data into the dataLayer is small and Snowplow is built to house as much data as you can throw at it. As a process, we recommend:

  1. Start off with the different objects that make up your product or service universe. If you’re a video site, like Youtube, than videos will be the main object that make up your universe. But users, comments, likes and channels are all other objects that make up the Youtube experience. (Each one of these will be represented in the CMS behind Youtube.)
  2. For each different object, think about what the key data points are that are interesting. For example, a video on Youtube will have an id, a name, an author / producer etc.
  3. Now consider what actions / events happen on a user journey. Each will typically involve the user interacting with one or more objects e.g. a video on the site. If the user likes a video, comments on a video or uploads a video, it will involve creating a new object.
  4. In general, each of the objects identified above should be pushed to the dataLayer, with each of the associated data points. It may not be necessary to push all the associated data points for each object, because it may be possible to infer some from another. (For example, if we know the id of a video, we might be able to lookup the author from the CMS at a later stage.) But we want to pass enough data points in with each object to support any analysis, that we might want to perform, down the line, on that object.
  5. The list of objects, data points, and events on the user journeys, should be documented. Those documents will be used in the next step, working out how to structure the data in the dataLayer

1.4 Work out how to structure the data passed into dataLayer

Broadly speaking, there are two occasions we can pass data points into the dataLayer:

  1. When the page loads
  2. When an event occurs. (Which might not correspond to a page load because it is AJAX.) This might include watching a video, adding an item to the shopping basket, submitting a purchase, logging in.

In general, if the data point is directly related to the webpage being loaded, it makes sense to push that data point into the data layer at page load time. For example, if on the product pages on an online shop, it would make sense to push key product details (name, sku, price, category) with the page load, by inserting the following code in the page before the container tags:

<body> <script type="text/javascript"> dataLayer = [{ 'productSku': 'pbz00123', 'productName': 'The Original Rider Waite Tarot cards', 'productPrice': '9.99' }]; </script> <!-- Google Tag Manager --> ... <!-- End Google Tag Manager --> </body>
Code language: HTML, XML (xml)

GTM might then pass these data points into Snowplow as page level custom variables, for example.

We might equally want to record these data points on catalogue pages, where multiple products are listed. In this case, we could pass the three data points (productSku, productName and productPrice) in for each product as follows:

<body> <script type="text/javascript"> dataLayer = [{ 'products': [ {'productSku': 'pbz00123', 'productName': 'The Original Rider Waite Tarot cards', 'productPrice': '9.99' }, {'productSku': 'pbz00124', 'productName': 'Aleicester Crowley Thoth Tarot', 'productPrice': '12.99' }, {'productSku': ...}, {'productSku': ...}, ... ] }]; </script> <!-- Google Tag Manager --> ... <!-- End Google Tag Manager --> </body>
Code language: HTML, XML (xml)

We could use this data to perform an analysis of which product on catalogue pages are most likely to be clicked on, and whether that varies by user segment, for example. Analogous data points related to videos and listing the videos displayed on a selection page could be used by a Youtube-like site that wanted to analyse what drove users to select particular videos from a selection.

In many cases, however, we will want to capture data related to specific events that occur on a user’s journey, like playing a video, when those events occur, rather than when a page loads. In these cases, we can use dataLayer.push function to add new data points to the layer when an AJAX event like watching a video occurs. For example, we might trigger the following with a video play:

dataLayer.push( 'event': 'playVideo', 'videoId': 'vid-000-123', 'videoName': 'Skateboarding dog', 'videoAuthor': 'user-00121' 'videoFormat': 'hd' );
Code language: JavaScript (javascript)

It is critical that whenever we want to capture data related to a specific event when that event occurs, the dataLayer.push function includes a field called event with a value set to the event type. That is because GTM uses the setting of value of the event field to trigger the firing of tags setup in GTM, and is hence essential to making Snowplow event tracking possible (because the Snowplow event tracking tag needs to fire following specific events) and the Snowplow ecommerce tracking possible (because that is, equally, triggered by specific purchase events.)

Now that we know what data we want to capture in the dataLayer, and when we want to capture each data point (either at page load time or with each event), we are in a position to finalise the documentation for the webmaster that makes it clear what variables to set in the dataLayer, and when. This will be the basis for integrating the dataLayer onto the website below.

Note: GA suggestions for data points and field names in the dataLayer

Google has a number of suggestions for what fields should be captured in the dataLayer, and how they should be labelled. Those can be found here.

For the most part, these are just suggestions. However, some of them are more than that. For example, if you want to use either Google Analytics ecommerce tracking, or Snowplow’s own ecommerce tracking (which is closely modelled on Google’s approach), you will need to set specific variables in your dataLayer. Instructions on how to do this is covered below in the corresponding section on ecommerce tracking.

1.5 Integrate the dataLayer onto your website

Now that we’ve decided (and documented) what data to push to the dataLayer, and when, your webmaster should be in a position to integrate the dataLayer calls into your website.

Note – although we’ve separated this step out from step 1.2 integrating your container tag on your website, in practice you’d want to carry out both these steps simultaneously.

1.6 Create variables stored in the dataLayer in the GTM UI

Passing data into GTM via the dataLayer is great – but to get any value from that data, we need to be able to pass it on to the tags that GTM manages, including Snowplow.

Doing so is simple, if a little time consuming. For every top-level data field passed into GTM (e.g. products, videoId etc.), we need to create a dataLayer variable in GTM. The value of this variable will be set when the value is passed into the dataLayer, and we’ll be able to pass the variable into any tags that are setup in GTM. (Instructions on how to do this for Snowplow tags will be given in the section on integrating Snowplow below.)

Variables are name-value pairs for which the value is populated during runtime. For example, the predefined variable named “url” has been defined such that its value is the current page URL.

Built-in (predefined) variables are a special category of variables that are pre-created and non-customizable. They replace the variables that used to be generated when creating a new container.

To create a new custom variable in GTM, click on the NEW button at the bottom of the GTM screen (when you are logged into your Account » Container » Variables).

Give your variable an appropriate name. For simplicity, we always use the same name used in the dataLayer, although that is not a requirement. Select Data Layer Variable type. Then enter the name of the variable, exactly as used in the HTML / JavaScript. (This is case sensitive.)

Save the new variable. It will now be visible in the container setup under “User-Defined Variables” section.

Some notes on variables

GTM comes pre-configured with a few (built-in) variables already, in particular event, referrer and url. The event is especially important. You can set GTM up to trigger the firing of tags when specific event types are pushed to the dataLayer. We use this to trigger both Snowplow event tracking tags, and e-commerce tracking tags, as explained below.

Back to top

2. Integrating Snowplow JavaScript tracking tags with Google Tag Manager

  1. Integrating Snowplow page tracking tags
  2. Publishing changes to GTM

2.1 Integrating Snowplow page tracking tags

This is the simplest tag to integrate.

First, click on the New button within Tags section of the container.

Give the tag a suitable name e.g. “Snowplow page tracker” and select Custom HTML Tag as your product. Then paste in the standard Snowplow page tracking code in the HTML box.

The actual code you need to insert is:

<!-- Snowplow starts plowing --> <script type="text/javascript"> ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[]; p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments) };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1; n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","//cdn.jsdelivr.net/gh/snowplow/sp-js-assets@2.5.1/sp.js","snowplow")); window.snowplow('newTracker', 'cf', '{{MY-COLLECTOR-URI}}', { // Initialise a tracker appId: '{{MY-SITE-ID}}', cookieDomain: '{{MY-COOKIE-DOMAIN}}' }); window.snowplow('trackPageView'); </script> <!-- Snowplow stops plowing -->
Code language: HTML, XML (xml)

You will need to update {{MY-COLLECTOR-URI}} with the collector domain details you created as part of the collector setup. (If you are using a version of Snowplow hosted by the Snowplow team, we will provide you with a domain to enter.) It will look something like c.mydomain.com. There is no need to include a protocol (“http” or “https”) – the tracker does this automatically.

The appId and cookieDomain fields are optional: the first is used if you are running Snowplow across different applications and want to distinguish data for each easily. Setting a custom cookie domain is useful if you are tracking users across multiple subdomains e.g. ‘blog.mysite.com’, ‘www.mysite.com’, ‘mysite.com’. Full instructions on the use of both these methods can be found in the JavaScript Tracker technical documentation.

If you are hosting your own Snowplow JavaScript file (see the guide to [self-hosting snowplow.js](self hosting snowplow js)), then you need to update the tag above, swapping your own tracker location (the one from which you serve sp.js):

;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[]; p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments) };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1; n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","//{{YOUR_TRACKER_LOCATION}}/sp.js","snowplow"));
Code language: JavaScript (javascript)

Once the tag is inserted, we need to instruct GTM to fire this tag on every page load. It is straightforward here: click on Continue button. This will apply the default tag firing option which is “Once per event”.

On the Fire On step select All pages. This will ensure that the tag is fired for every page load. (If you had tags on e.g. www.mysite.com and test.mysite.com, you could create an exception filter with a different URL regexp to only fire the tags on the production, rather than test site, and assign that rule to the tag.)

Now you’re done – click Create Tag. The new tag should be listed in the container summary screen.

Note: although set up, the tag won’t fire until this update is published. We cover how to publish the configurations made above in the next section.

2.2 Publishing changes to GTM

Once you have setup all your tags, triggers and variables in GTM, you need to publish the changes before they will take effect on your website(s).

This is a three step process:

  1. Preview and debug
  2. Create a version with all the most recent changes / updates
  3. When you are confident it is working as expected, publish it

Note: Your tags, triggers, and variables are validated on attempt to publish. You could start from any of the above processes as GTM will lead you in the above order anyway. That is if you start, say, from the last step (“Publish”) GMT will check you work for validity first and it won’t let you to proceed until you have debugged your variables and HTML code. If all is good, it will create a version automatically before publishing. Likewise, when trying to create a version first you will be forced to correct the errors (if any) in debug mode first.

Choosing any of the above steps is simple: Click on the button next to Publish to bring the dropdown menu up listing the steps.

Click on Preview to check for any problem. If GMT validation fails it will report it back with the screen which looks like the one below. You might need to scroll down to see the full list. You are in debug mode.

The location field contains the links to the problematic configuration. Follow the links to either check and correct your code or find out more about the problem. When all is fixed preview the tags again. Since all the errors have been corrected you will be switched to preview (as opposed to debug) mode.

Now load a web page with the container in a tab in the same browser. You should see an additional GTM interface in the bottom half of the screen that indicates when different tags defined in the UI have been fired.

If you are happy that the setup works as expected, click the Publish button. The updates will be pushed to live.

In the event that it is not working as expected, you can go back and make the changes you require. You will need to create a new version, with the updates, before you can either preview them, or publish them.

Back to top

3. Integrating Snowplow JavaScript tracking tags with Enhanced E-commerce

You can send Enhanced E-commerce data to Snowplow as well as Google Analytics. For more information, see Integrating JavaScript tags with Enhanced E-commerce.