Snowplow is an open source datalogger that gives you access to event level data. This makes the data very powerful and allows you to make complex analysis with your data. At Blue Mango, we currently use it for advanced analysis like Conversion Attribution.

One of the new uses we want to explore is analysing A/B tests with Snowplow data. To do this, it would be nice to add A/B test data to all of our Snowplow data logs. To make this as convenient as possible, the code should be automated.

For this post, we use Visual Website Optimizer (VWO) as the source for our A/B testing data. Getting the VWO data automatically is quite easy.

Getting the VWO data##

To get all of the VWO data available on a webpage, we take the following two things into account:

  • Get the available VWO cookies based on a regular expression; and
  • Transform the cookie strings into short test ID’s.

We used a regular expression to automatically get all the VWO experiment cookies from the list of the website’s cookies. We chose to transform the cookie strings into shorter test ID’s to maximize readability. For example: a test cookie contains the following information: _vis_opt_exp_21_combi=2. This means that for VWO test 21 the current variant is 2. So to only push the information we need, we transform this string to vwo-21-2.

Get VWO test info code

 /**
    * get Visual Website Optimizer cookies
    * @returns {array}
    */
    function getVwoTests(){
        var cs=document.cookie.split(/;\s*/), vwoCookies=[], i;
        for (i=0; i<cs.length; i++) {
          //check if cookie matches VWO cookie regex
          if (cs[i].match(/^_vis_opt_exp_.*_combi/)) {
            //modify the cookie string to VWO-TESTID-VARIANT and push to array
        vwoCookies.push('vwo-'+cs[i].match(/\d+/g)[0]+'-'+cs[i].slice(-1));
          }
        }
        return vwoCookies;
    };
  

The code above returns the following array:

["vwo-69-3", "vwo-72-4"]
  

The next step is to add this array to your Snowplow data logs. And personally, I think the custom context is the best place to put this.

Snowplow custom context##

The custom context is the place to add custom meta data to your data logs. It’s a good place to add cookie opt-in information (true/false) to all Snowplow logs. At Blue Mango, we do this to make sure we only use user data of users that have given a cookie consent. Here’s an example of how to add custom context data to a standard pageview:

Snowplow Pageview with custom context example

  snaq('trackPageView', document.title, {
      'sp-settings': {
        //addcustom data
      }
    });
  

Note that the second parameter is document.title, this mimics the default value Snowplow uses for a pagename. After this, it’s quite easy to add the testing information with the getVwoTests function:

Snowplow Pageview with Custom Context & VWO info example

 /**
    * get Visual Website Optimizer cookies
    * @returns {array}
    */
    function getVwoTests(){
      var cs=document.cookie.split(/;\s*/), vwoCookies=[], i;
      for (i=0; i<cs.length; i++) {
      //check if cookie matches VWO cookie regex
      if (cs[i].match(/^_vis_opt_exp_.*_combi/)) {
        //modify the cookie string to VWO-TESTID-VARIANT and push to array
      vwoCookies.push('vwo-'+cs[i].match(/\d+/g)[0]+'-'+cs[i].slice(-1));
        }
      }
      return vwoCookies;
    };

    snaq('trackPageView', document.title, {
      'sp-settings': {
        'abtests': getVwoTests()
      }
    })
  

By using a function to return this information, you make sure that every time you log a pageview, the VWO information is updated automatically.

To take this a step further, you can create a global function to return the custom context. After that, you can use that function to add custom context information to all Snowplow data logs (note that this is always the last parameter to add in your event scripts).

Snowplow events with return custom context examples

 /**
    * get Snowplow custom context object
    * @returns {json}
    */
    function getSnowplowCustomContextObject(){
      var snowplowCustomContextObject = {
        'sp-settings': {
          //add snowplow custom data
        }
      };
      return snowplowCustomContextObject;
    };

    //pageview example
    snaq('trackPageView', document.title, getSnowplowCustomContextObject());

    //event example
    snaq('trackStructEvent', 'category', 'action', 'label', property, value, getSnowplowCustomContextObject());

    //transaction item exmample
    snaq('addItem',
       'orderid',
       'sku',
       'productname',
       'product category',
       product price,
       product quantity,
       'EUR',
     getSnowplowCustomContextObject()
    );

  

As a final example, here’s the complete code snippet with the VWO information, the custom context function and a Snowplow pageview:

Snowplow Pageview with return custom context function & VWO info

 /**
    * get Visual Website Optimizer cookies
    * @returns {array}
    */
    function getVwoTests(){
        var cs=document.cookie.split(/;\s*/), vwoCookies=[], i;
        for (i=0; i<cs.length; i++) {
          if (cs[i].match(/^_vis_opt_exp_.*_combi/)) {
        vwoCookies.push('vwo-'+cs[i].match(/\d+/g)[0]+'-'+cs[i].slice(-1));
          }
        }
        return vwoCookies;
    };

   /**
    * get Snowplow custom context object
    * @returns {json}
    */
    function getSnowplowCustomContextObject(){
      var snowplowCustomContextObject = {
        'sp-settings': {
          'abtests': getVwoTests()
        }
      };
      return snowplowCustomContextObject;
    };

    /*pageview example*/
    snaq('trackPageView', document.title, getSnowplowCustomContextObject());
  

Pitfall##

There’s a pitfall to this code. If you use a tag manager (like Google Tag Manager), the following user behaviour may occur:

  • User visits website;
  • Snowplow is loaded (with pageview & no VWO cookies);
  • VWO is loaded and sets the cookies;
  • The user leaves the website.

In this scenario, there won’t be any VWO related user data in Snowplow. Though the user is a ‘bounce’, you still want to add this information to the Snowplow data. To fix this, make sure to fire a Snowplow event (with custom context) after VWO loads.

Basic example to track each VWO visit

  /*start VWO Code*/
    // put your VWO code here
    /*end VWO Code*/

    /*track VWO Visit*/
    snaq('trackStructEvent', 'VWO', 'Visit', '', '', 0, getSnowplowCustomContextObject());
  

Next Steps##

With VWO information and custom context in place, you are ready for analysis. We’ll also be working on a similar script for Optimizely. We’ll create post for that once we have it ready.

Leave a Reply