tabler logo Tushar Gupta's Blog GTM Audit Tool
tgupta logo Tushar Gupta's Blog

Guide to create Snowplow Pageview Custom template for Google Tag Manager (GTM)

May 27, 2019 in Analytics

Since Google Tag Manager has rolled out Custom Templates. I have been trying to create some examples for the general use case. In this post, we will learn how to create a standard pageview snowplow pixel. I have tried to keep it as simple as possible.

If you want to have a quick recap at what are custom templates. Please have a read here: Custom Templates : Google Tag Manager

Standard Snowplow Pageview Pixel

Below is the snippet we have the standard snowplow pageview pixel. This pixel includes some important variables that we will create them as inputs from the user while creating the tag.

  
    // Snowplow starts plowing 
    
    (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", "//d1fc8wv8zag5ca.cloudfront.net/2.6.2/sp.js", "snowplow"));
        window.snowplow('newTracker', 'cf', '{{MY-COLLECTOR-URI}}', 
          { // Initialise a tracker
            appId: '{{MY-SITE-ID}}',
            cookieDomain: '{{MY-COOKIE-DOMAIN}}'
    });
    window.snowplow('trackPageView')
   
    // Snowplsow stops plowing 
  
Let's create the Snowplow Pageview Custom template for GTM

Defining Information Tab

This is an unofficial version of snowplow pageview template created just for common use. We will use the name and description to make sure it serves the purpose. The details that we used are in the below image.

This is how it will look like in the tags tab


Creating UI for the Pixel Inputs

We will define important variables as fields required to be entered by the users to create the tag. The list of the fields are as below

  1. appId
    • Field Type - Text Field
    • Purpose - Unique identifier for website / application
    • Required - Yes
    • Example Value - e.g: my-tgupta-blog
  2. platformType
    • Field Type - Dropdown
    • Purpose - The platform the app runs on
    • Required - Yes
    • Example Value - e.g: app / mob / web
  3. sp.js location
    • Field Type - dropdown
    • Purpose - Your SP js location with https://
    • Required - Yes
    • Example Value - e.g: https://example.cloudfront.net/2.10.2/sp.js
  4. requestType
    • Field Type - Text
    • Purpose - Request Type
    • Required - Yes
    • Example Value - e.g: get / post
  5. endpoint
    • Field Type - Text
    • Purpose - Collector endpoint
    • Required - Yes
    • Example Value - e.g: d3rkrsqld9gmqf.cloudfront.net
  6. trackerName
    • Field Type - Text
    • Purpose - Custom Tracker Name
    • Required - Yes
    • Example Value - e.g: cf


Code for the Template

This is the tricky part. Let's understand each line step by step. We need to break the standard Javascript snippet into the sandboxed JavaScript.

Step 1: Defining utilities

Since templates in Google Tag Manager uses sandboxed JavaScript, we have to import the utilities using a global require function. The Custom Templates API is documented with their usage

  
  // Create constants to use utilities //
  
  /*logToConsole: To log and debug values*/
  const log = require('logToConsole');

  /*createQueue:- Creates an array in the window (if it doesn't already exist) and returns a function that will push values onto that array.*/
  const createQueue = require('createQueue');

  /*callInWindow:- Allows you to call functions from a path off the window object*/
  const callInWindow = require('callInWindow');

  /*copyFromWindow:- Copies a variable from the window object*/
  const copyFromWindow = require('copyFromWindow');

  /*setInWindow:- Sets the given value in the window at the given key*/
  const setInWindow = require('setInWindow');

  /*injectScript:- Adds a script tag to the page to load the given URL asynchronously*/
  const injectScript = require('injectScript');

  /*callLater:- Schedules a call a function to occur asynchronously*/
  const cl = require('callLater');
  

Step 2: Creating Pageview function (to be called once we inject the script)

- First, we create a function that will return the global snowplow object.

  
  const getSpq = () => {}
    

- Then we define the GlobalSnowplowNamespace array and insert snowplow as key

  
  let gp = createQueue('GlobalSnowplowNamespace');
  gp("snowplow");
    

- After this, we define the global window snowplow object. If it is available then we return the same

  
  // Generate snowplow (if available retun)
  let snowplow = copyFromWindow('snowplow');

  if (snowplow) {
      return snowplow;
  }
    

- Then we initialize the snowplow.q.push global method. Create the snowplow.q and finally return snowplow object

  
  // Initialize the 'snowplow.q.push' global method 
  setInWindow('snowplow', function() {
      callInWindow('snowplow.q.push', arguments);
  });
  
  // Create the snowplow.q
  createQueue('snowplow.q');

  // Return the global 'snowplow' method, created above
  return copyFromWindow('snowplow');
    

- At last we define the options object from the input fields and trigger the pageview

  
  const sp = getSpq();
  const options = {
      appId: data.appId,
      platform: data.platformType,
      post: data.requestType,
      contexts: {
          webPage: true,
          performanceTiming: true
      }
  };

  sp('newTracker', data.trackerName, data.endpoint, options);

  //track Pageview
  sp('trackPageView');
    

Step 3: Injecting the Script sp.js

- We will use injectScript to inject sp.js. We also have to delay our pageview function call using callLater(pageView) so that we get the inject script and snowplow function becomes active.

  
  // Delay the function call to snowplow so that teh script injects the object
  injectScript(data.loc, callLater(pageView), data.gtmOnFailure, 'snowplow');

  data.gtmOnSuccess();
    

Permissions

For each key used for accessing global variables, we need to specify the permissions as what that key can do. read , write or execute.CONFIGURATION

We also need to specify the pattern for the Cloudfront sp.js injection. If you are changing the hosting of sp.js, you need to change the inject scripts pattern


Download source code (.tpl) file

Click here to download .tpl file

How to use .tpl file?

To import a template file into your Google Tag Manager container, follow these steps:

  • Download the .tpl file you want to import.
  • Create a new template in Google Tag Manager (either tag or variable, depending on which type you are importing).
  • In the action menu in the top right corner of the template editor, choose Import.
  • Select the .tpl file from your container.

Importing a template file like this will overwrites any work you might have done in the underlying template. Always try to import to a newly created template.




Related topics