1. Overview

The Ghct JavaScript Tracker works in much the same way as JavaScript trackers for other major web analytics solutions including Google Analytics and Omniture. We have tried, as far as possible, to keep the API very close to that used by Google Analytics, so that users who have implemented Google Analytics JavaScript tags have no difficulty also implementing the Ghct JavaScript tags.

Tracking is done by inserting JavaScript tags onto pages. These tags run functions defined in ghct.js, that trigger GET requests of the Ghct pixel. The JavaScript functions append data points to be passed into Ghct onto the query string for the GET requests. These then get logged by the Ghct collector. For a full list of data points that can be passed into Ghct in this way, please refer to the Ghct tracker protocol documentation.

The JavaScript Tracker supports both synchronous and asynchronous tags. We recommend the asynchronous tags in nearly all instances, as these do not slow down page load times.

  1. General parameters
  2. Tracking specific events

1.1 Quick Start

For quick start/setting up the tracker on your site just copy the below script and paste it inside the head tag.

Replace <enter_your_site_appid> with an application id for your site. This will be attached to every event the tracker fires.

<html>
  <head>
  <title>Example Home Page</title>
  

  
  
  </head>
  <body>
      Example for initializing GHC Tracker
  </body>
  </html>

The Three parts involved in the above script are :

LOADING/INITIALIZING THE SCRIPT.
INITIALIZE A TRACKER.
TRACKING THE EVENTS.

1.1.0 Loading/Initializing the script

Below script is responsible for loading the ghct tracker.js into the page which you are going to track.

; (function (p, l, o, w, i, n, g) { if (!p[i]) { p.GlobalGhctNamespace = p.GlobalGhctNamespace || []; p.GlobalGhctNamespace.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", "//developer.goodharvest.co/ghct.js", "ghct"));

1.1.1 Initialize a tracker

All the tracked events are sent to (d17f2sx66vnl5s.cloudfront.net) this collector url.

window.ghct('newTracker', 'cf', 'd17f2sx66vnl5s.cloudfront.net', { appId: 'mysite', cookieName: '_ghc_' });

For more options while initializing the tracker refer General Parameters

1.1.2 Tracking the events

Example for tracking a Page View Event.

window.ghct('trackPageView');

For tracking more events --> Tracking specific events

Back to top

3. Tracking specific events

Ghct has been built to enable users to track a wide range of events that occur when consumers interact with their websites and webapps. We are constantly growing the range of functions available in order to capture that data more richly.

3.1 Pageviews

Page views are tracked using the trackPageView method. This is generally part of the first Ghct tag to fire on a particular web page. As a result, the trackPageView method is usually deployed straight after the tag that also invokes the Ghct JavaScript (ghct.js) e.g.

<!-- ghct starts -->
  <script type="text/javascript">
  ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalGhctNamespace=p.GlobalGhctNamespace||[];
  p.GlobalGhctNamespace.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","//developer.goodharvest.co/ghct.js","ghct_name_here"));
  
  window.ghct_name_here('enableActivityTracking', 30, 10);
  
  window.ghct_name_here('trackPageView');
  
   </script>
  <!-- ghct stops -->

3.1.1 trackPageView

Track pageview is called using the simple:

window.ghct_name_here('trackPageView');

This method automatically captures the URL, referrer and page title (inferred from the <title> tag.

If you wish, you can override the title with a custom value:

window.ghct_name_here('trackPageView', 'my custom page title');

trackPageView can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

Additionally, you can pass a function which returns an array of zero or more contexts to trackPageView. For the page view and for all subsequent page pings, the function will be called and the contexts it returns will be added to the event.

For example:

// Turn on page pings every 10 seconds
  window.ghct('enableActivityTracking', 10, 10);
  
  window.ghct(
    'trackPageView',
  
    // no custom title
    null,
  
    // The usual array of static contexts
    [{
      schema: 'iglu:com.acme/static_context/jsonschema/1-0-0',
      data: {
        staticValue: new Date().toString()
      }
    }],
  
    // Function which returns an array of custom contexts
    // Gets called once per page view / page ping
    function() {
      return [{
        schema: 'iglu:com.acme/dynamic_context/jsonschema/1-0-0',
        data: {
          dynamicValue: new Date().toString()
        }
      }];
    }
  );

The page view and every subsequent page ping will have both a static_context and a dynamic_context attached. The static_contexts will all have the same staticValue, but the dynamic_contexts will have different dynamicValues since a new context is created for every event.

Back to top [Back to JavaScript technical documentation contents][contents]

3.2 Track engagement with a web page over time: page pings

As well as tracking page views, we can monitor whether a user continues to engage with a page over time, and record how he / she digests content on the page over time.

That is accomplished using 'page ping' events. If activity tracking is enabled, the web page is monitored to see if a user is engaging with it. (E.g. is the tab in focus, does the mouse move over the page, does the user scroll etc.) If any of these things occur in a set period of time, a page ping event fires, and records the maximum scroll left / right and up / down in the last ping period. If there is no activity in the page (e.g. because the user is on a different tab in his / her browser), no page ping fires.

3.2.1 enableActivityTracking

Page pings are enabled by:

window.ghct_name_here('enableActivityTracking', minimumVisitLength, heartBeat);

where minimumVisitLength is the time period from page load before the first page ping occurs, in seconds. Heartbeat is the number of seconds between each page ping, once they have started. So, if you executed:

window.ghct_name_here('enableActivityTracking', 30, 10);
  
  window.ghct_name_here('trackPageView');

The first ping would occur after 30 seconds, and subsequent pings every 10 seconds as long as the user continued to browse the page actively.

Notes:

  • In general this is executed as part of the main Ghct tracking tag. As a result, you can elect to enable this on specific pages.
  • The enableActivityTracking method must be called before the trackPageView method.
  • Activity tracking will be disabled if either minimumVisitLength or heartBeat is not integer. This is to prevent relentless callbacks.

3.2.2 updatePageActivity

You can also trigger a page ping manually with:

window.ghct_name_here('updatePageActivity');

This is particularly useful when a user is passively engaging with your content, e.g. watching a video.

Back to top [Back to JavaScript technical documentation contents][contents]

3.3 Ecommerce tracking

Modelled on Google Analytics ecommerce tracking capability, Ghct uses three methods that have to be used together to track online transactions:

  1. Create a transaction object. Use addTrans() method to initialize a transaction object. This will be the object that is loaded with all the data relevant to the specific transaction that is being tracked including all the items in the order, the prices of the items, the price of shipping and the order_id.
  2. Add items to the transaction. Use the addItem() method to add data about each individual item to the transaction object.
  3. Submit the transaction to Ghct using the trackTrans() method, once all the relevant data has been loaded into the object.

3.3.1 addTrans

The addTrans method creates a transaction object. It takes nine possible parameters, two of which are required:

Parameter Description Required? Example value
orderId Internal unique order id number for this transaction Yes '1234'
affiliation Partner or store affiliation No 'Womens Apparel'
total Total amount of the transaction Yes '19.99'
tax Tax amount of the transaction No '1.00'
shipping Shipping charge for the transaction No '2.99'
city City to associate with transaction No 'San Jose'
state State or province to associate with transaction No 'California'
country Country to associate with transaction No 'USA'
currency Currency to associate with this transaction No 'USD'

For example:

window.ghct_name_here('addTrans',
      '1234',           // order ID - required
      'Acme Clothing',  // affiliation or store name
      '11.99',          // total - required
      '1.29',           // tax
      '5',              // shipping
      'San Jose',       // city
      'California',     // state or province
      'USA',            // country
      'USD'             // currency
    );

addTrans can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

Back to top [Back to JavaScript technical documentation contents][contents]

3.3.2 addItem

The addItem method is used to capture the details of each product item included in the transaction. It should therefore be called once for each item.

There are six potential parameters that can be passed with each call, four of which are required:

Parameter Description Required? Example value
orderId Order ID of the transaction to associate with item Yes '1234'
sku Item's SKU code Yes 'pbz0001234'
name Product name No, but advisable (to make interpreting SKU easier) 'Black Tarot'
category Product category No 'Large'
price Product price Yes '9.99'
quantity Purchase quantity Yes '1'
currency Product price currency No 'USD'

For example:

window.ghct_name_here('addItem',
      '1234',           // order ID - required
      'DD44',           // SKU/code - required
      'T-Shirt',        // product name
      'Green Medium',   // category or variation
      '11.99',          // unit price - required
      '1',              // quantity - required
      'USD'             // currency
    );

addItem can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

3.3.3 trackTrans

Once the transaction object has been created (using addTrans) and the relevant item data added to it using the addItem method, we are ready to send the data to the collector. This is initiated using the trackTrans method:

window.ghct_name_here('trackTrans');

3.3.4 Putting the three methods together: a complete example

<html>
  <head>
  <title>Receipt for your clothing purchase from Acme Clothing</title>
  <script type="text/javascript">
  
    ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalGhctNamespace=p.GlobalGhctNamespace||[];
    p.GlobalGhctNamespace.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","//developer.goodharvest.co/ghct.js","ghct_name_here"));
  
    window.ghct_name_here('newTracker', 'cf', 'd3rkrsqld9gmqf.cloudfront.net');
    window.ghct_name_here('enableActivityTracking', 30, 10)
    window.ghct_name_here('trackPageView');
    window.ghct_name_here('enableLinkClickTracking');
  
    window.ghct_name_here('addTrans',
      '1234',           // order ID - required
      'Acme Clothing',  // affiliation or store name
      '11.99',          // total - required
      '1.29',           // tax
      '5',              // shipping
      'San Jose',       // city
      'California',     // state or province
      'USA'             // country
    );
  
     // add item might be called for every item in the shopping cart
     // where your ecommerce engine loops through each item in the cart and
     // prints out _addItem for each
    window.ghct_name_here('addItem',
      '1234',           // order ID - required
      'DD44',           // SKU/code - required
      'T-Shirt',        // product name
      'Green Medium',   // category or variation
      '11.99',          // unit price - required
      '1'               // quantity - required
    );
  
    // trackTrans sends the transaction to Ghct tracking servers.
    // Must be called last to commit the transaction.
    window.ghct_name_here('trackTrans'); //submits transaction to the collector
  
  </script>
  </head>
  <body>
  
    Thank you for your order.  You will receive an email containing all your order details.
  
  </body>
  </html>

Back to top [Back to JavaScript technical documentation contents][contents]

3.4 Social tracking

Social tracking will be used to track the way users interact with Facebook, Twitter and Google + widgets, e.g. to capture "like this" or "tweet this" events.

3.4.1 trackSocialInteraction

The trackSocialInteraction method takes three parameters:

Parameter Description Required? Example value
action Social action performed Yes 'like', 'retweet'
network Social network Yes 'facebook', 'twitter'
target Object social action is performed on e.g. page ID, product ID No '19.99'

The method is executed in as:

window.ghct_name_here('trackSocialInteraction', action, network, target);

For example:

window.ghct_name_here('trackSocialInteraction', 'like', 'facebook', 'pbz00123');

Or if the optional parameters were left off:

window.ghct_name_here('trackSocialInteraction', 'like', 'facebook');

trackSocialInteraction can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

Back to top [Back to JavaScript technical documentation contents][contents]

3.5 Campaign tracking

Campaign tracking is used to identify the source of traffic coming to a website.

At the highest level, we can distinguish paid traffic (that derives from ad spend) with non paid traffic: visitors who come to the website by entering the URL directly, clicking on a link from a referrer site or clicking on an organic link returned in a search results, for example.

In order to identify paid traffic, Ghct users need to set five query parameters on the links used in ads. Ghct checks for the presence of these query parameters on the web pages that users load: if it finds them, it knows that that user came from a paid source, and stores the values of those parameters so that it is possible to identify the paid source of traffic exactly.

If the query parameters are not present, Ghct reasons that the user is from a non paid source of traffic. It then checks the page referrer (the url of the web page the user was on before visiting our website), and uses that to deduce the source of traffic:

  1. If the URL is identified as a search engine, the traffic medium is set to "organic" and Ghct tries to derive the search engine name from the referrer URL domain and the keywords from the query string.
  2. If the URL is a non-search 3rd party website, the medium is set to "referrer". Ghct derives the source from the referrer URL domain.

3.5.1 Identifying paid sources

Your different ad campaigns (PPC campaigns, display ads, email marketing messages, Facebook campaigns etc.) will include one or more links to your website e.g.:

<a href="http://mysite.com/myproduct.html">Visit website</a>

We want to be able to identify people who've clicked on ads e.g. in a marketing email as having come to the site having clicked on a link in that particular marketing email. To do that, we modify the link in the marketing email with query parameters, like so:

<a href="http://mysite.com/myproduct.html?utm_source=newsletter-october&utm_medium=email&utm_campaign=cn0201">Visit website</a>

For the prospective customer clicking on the link, adding the query parameters does not change the user experience. (The user is still directed to the webpage at http://mysite.com/myproduct.html.) But Ghct then has access to the fields given in the query string, and uses them to identify this user as originating from the October Newsletter, an email marketing campaign with campaign id = cn0201.

3.5.2 Anatomy of the query parameters

Ghct uses the same query parameters used by Google Analytics. Because of this, Ghct users who are also using GA do not need to do any additional work to make their campaigns trackable in Ghct as well as GA. Those parameters are:

Parameter Name Description
utm_source Campaign source Identify the advertiser driving traffic to your site e.g. Google, Facebook, autumn-newsletter etc.
utm_medium Campaign medium The advertising / marketing medium e.g. cpc, banner, email newsletter, in-app ad, cpa
utm_campaign Campaign id A unique campaign id. This can be a descriptive name or a number / string that is then looked up against a campaign table as part of the analysis
utm_term Campaign term(s) Used for search marketing in particular, this field is used to identify the search terms that triggered the ad being displayed in the search results.
utm_content Campaign content Used either to differentiate similar content or two links in the same ad. (So that it is possible to identify which is generating more traffic.)

The parameters are descibed in the [Google Analytics help page][gahelppage]. Google also provides a [urlbuilder][gaurlbuilder] which can be used to construct the URL incl. query parameters to use in your campaigns.

Back to top [Back to JavaScript technical documentation contents][contents]

3.6 Ad tracking methods

Ghct tracking code can be included in ad tags in order to track impressions and ad clicks. This is used by e.g. ad networks to identify which sites and web pages users visit across a network, so that they can be segmented, for example.

Each ad tracking method has a costModel field and a cost field. If you provide the cost field, you must also provide one of 'cpa', 'cpc', and 'cpm' for the costModel field.

It may be the case that multiple ads from the same source end up on a single page. If this happens, it is important that the different Ghct code snippets associated with those ads not interfere with one another. The best way to prevent this is to randomly name each tracker instance you create so that the probability of a name collision is negligible. See Managing multiple trackers for more on having more than one tracker instance on a single page.

Below is an example of how to achieve this when using Ghct ad impression tracking.

<!-- Ghct starts -->
  <script type="text/javascript">
  
  // Wrap script in a closure.
  // This prevents rnd from becoming a global variable.
  // So if multiple copies of the script are loaded on the same page,
  // each instance of rnd will be inside its own namespace and will
  // not overwrite any of the others.
  (function(){
    // Randomly generate tracker namespace to prevent clashes
    var rnd = Math.random().toString(36).substring(2);
  
    // Load Ghct
    ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalGhctNamespace=p.GlobalGhctNamespace||[];
    p.GlobalGhctNamespace.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","//developer.goodharvest.co/ghct.js","ghct_pm"));
  
    // Create a new tracker namespaced to rnd
    window.ghct_pm('newTracker', rnd, 'dgrp31ac2azr9.cloudfront.net', {
      appId: 'myApp',
      platform: 'web'
    });
  
    // Replace the values below with magic macros from your adserver
    window.ghct_pm('trackAdImpression:' + rnd,
      '67965967893',            // impressionId
      'cpm',                    // costModel - 'cpa', 'cpc', or 'cpm'
      5.5,                      // cost
      'http://www.example.com', // targetUrl
      '23',                     // bannerId
      '7',                      // zoneId
      '201',                    // advertiserId
      '12'                      // campaignId
    );
  }());
  </script>
  <!-- Ghct stops -->

Even if several copies of the above script appear on a page, the trackers created will all (probably) have different names and so will not interfere with one another. The same technique should be used when tracking ad clicks. The below examples for trackAdImpression and trackAdClick assume that rnd has been defined in this way.

3.6.1 trackAdImpression

Ad impression tracking is accomplished using the trackAdImpression method. Here are the arguments it accepts:

Name Required? Description Type
impressionId No Identifier for the particular impression instance string
costModel No* The cost model for the campaign: 'cpc', 'cpm', or 'cpa' string
cost No* Ad cost number
targetUrl No* The destination URL string
bannerId No Adserver identifier for the ad banner (creative) being displayed string
zoneId No Adserver identifier for the zone where the ad banner is located string
advertiserID No Adserver identifier for the advertiser which the campaign belongs to string
campaignId No Adserver identifier for the ad campaign which the banner belongs to string

* Note: There are the following restrictions in place

  • targetUrl should have at least 1 character
  • cost should have a minimum value of 0
  • costModel has to be present as cost depends on it

An example:

window.ghct_name_here('trackAdImpression:' + rnd,
  
      '67965967893',             // impressionId
      'cpm',                     // costModel - 'cpa', 'cpc', or 'cpm'
       5.5,                      // cost
      'http://www.example.com',  // targetUrl
      '23',                      // bannerId
      '7',                       // zoneId
      '201',                     // advertiserId
      '12'                       // campaignId
  );

Ad impression events are implemented as Ghct unstructured events. [Here][ad-impression-schema] is the JSON schema for an ad impression event.

trackAdImpression can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

You will want to set these arguments programmatically, across all of your ad zones/slots. For guidelines on how to achieve this with the [OpenX adserver][openx], please see the following section 3.6.4.

3.6.2 trackAdClick

Ad click tracking is accomplished using the trackAdClick method. Here are the arguments it accepts:

Name Required? Description Type
targetUrl Yes The destination URL string
clickId No Identifier for the particular click instance string
costModel No The cost model for the campaign: 'cpc', 'cpm', or 'cpa' string
cost No Ad cost number
bannerId No Adserver identifier for the ad banner (creative) being displayed string
zoneId No Adserver identifier for the zone where the ad banner is located string
advertiserID No Adserver identifier for the advertiser which the campaign belongs to string
campaignId No Adserver identifier for the ad campaign which the banner belongs to string

An example:

window.ghct_name_here('trackAdClick:' + rnd,
  
      'http://www.example.com',  // targetUrl
      '12243253',                // clickId
      'cpm',                     // costModel
       2.5,                      // cost
      '23',                      // bannerId
      '7',                       // zoneId
      '67965967893',             // impressionId - the same as in trackAdImpression
      '201',                     // advertiserId
      '12'                       // campaignId
  );

Ad click events are implemented as Ghct unstructured events.[Here][ad-click-schema] is the JSON schema for an ad click event.

trackAdClick can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

3.6.3 trackAdConversion

Use the trackAdConversion method to track ad conversions. Here are the arguments it accepts:

Name Required? Description Type
conversionId No Identifier for the particular conversion instance string
costModel No The cost model for the campaign: 'cpc', 'cpm', or 'cpa' string
cost No Ad cost number
category No Conversion category number
action No The type of user interaction, e.g. 'purchase' string
property No Describes the object of the conversion string
initialValue No How much the conversion is initially worth number
advertiserID No Adserver identifier for the advertiser which the campaign belongs to string
campaignId No Adserver identifier for the ad campaign which the banner belongs to string

An example:

window.ghct_name_here('trackAdConversion',
  
      '743560297', // conversionId
      10,          // cost
      'ecommerce', // category
      'purchase',  // action
      '',          // property
      99,          // initialValue - how much the conversion is initially worth
      '201',       // advertiserId
      'cpa',       // costModel
      '12'         // campaignId
  );

Ad conversion events are implemented as Ghct unstructured events. [Here][ad-conversion-schema] is the schema for an ad conversion event.

trackAdConversion can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

3.6.4 Example: implementing impression tracking with Ghct and OpenX

Most ad servers enable you to append custom code to your ad tags. Here's what the zone append functionality looks like in the OpenX adserver (OnRamp edition):

![zoneappend][zoneappend]

You will need to populate the ad zone append field with Ghct tags for every ad zone/unit which you use to serve ads across your site or network. Read on for the Ghct HTML code to use for OpenX.

OpenX: Ghct impression tracking using magic macros

Because OpenX has a feature called [magic macros][magicmacros], it is relatively straightforward to pass the banner, campaign and user ID arguments into the call to trackAdImpression() (advertiser ID is not available through magic macros).

The full HTML code to append, using asynchronous Ghct invocation, looks like this:

<!-- Ghct starts -->
  <script type="text/javascript">
  ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalGhctNamespace=p.GlobalGhctNamespace||[];
  p.GlobalGhctNamespace.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","//developer.goodharvest.co/ghct.js","ghct_name_here"));
  
  // Update tracker constructor to use your CloudFront distribution subdomain
  window.ghct_name_here('newTracker', 'cf', 'patldfvsg0d8w.cloudfront.net');
  
  window.ghct_name_here('trackAdImpression', '{impressionId}' '{costModel}', '{cost}', '{targetUrl}', '{bannerid}', '{zoneid}', '{advertiserId}', '{campaignid}'); // OpenX magic macros. Leave this line as-is
  
   </script>
  <!-- Ghct stops -->

Once you have appended this code to all of your active ad zones, Ghct should be collecting all of your ad impression data.

Back to top

3.7 Tracking custom structured events

There are likely to be a large number of AJAX events that can occur on your site, for which a specific tracking method is part of Ghct. Examples include:

  • Playing a video
  • Adding an item to basket
  • Submitting a lead form

Our philosophy in creating Ghct is that users should capture "every" consumer interaction and work out later how to use this data. This is different from traditional web analytics and business intelligence, that argues that you should first work out what you need, and only then start capturing the data.

As part of a Ghct implementation, therefore, we recommend that you identify every type of AJAX interaction that a user might have with your site: each one of these is an event that will not be captured as part of the standard page view tracking. All of them are candidates to track using trackStructEvent, if none of the other event-specific methods outlined above are appropriate.

3.7.1 trackStructEvent

There are five parameters can be associated with each structured event. Of them, only the first two are required:

Name Required? Description
Category Yes The name you supply for the group of objects you want to track e.g. 'media', 'ecomm'
Action Yes A string which defines the type of user interaction for the web object e.g. 'play-video', 'add-to-basket'
Label No An optional string which identifies the specific object being actioned e.g. ID of the video being played, or the SKU or the product added-to-basket
Property No An optional string describing the object or the action performed on it. This might be the quantity of an item added to basket
Value No An optional float to quantify or further describe the user action. This might be the price of an item added-to-basket, or the starting time of the video where play was just pressed

The async specification for the trackStructEvent method is:

window.ghct_name_here('trackStructEvent', 'category','action','label','property','value');

An example of tracking a user listening to a music mix:

window.ghct_name_here('trackStructEvent', 'Mixes', 'Play', 'MrC/fabric-0503-mix', '', '0.0');

Note that in the above example no value is set for the event property.

trackStructEvent can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

Back to top [Back to JavaScript technical documentation contents][contents]

3.8 Tracking custom self-describing (unstructured) events

Note that this is only available on version 2.7.0 and above of the JS tracker.

You may wish to track events on your website or application which are not directly supported by Ghct and which structured event tracking does not adequately capture. Your event may have more than the five fields offered by trackStructEvent, or its fields may not fit into the category-action-label-property-value model. The solution is Ghct's self-describing events (previously known as unstructured). Self-describing events use JSONs which can have arbitrarily many fields.

To define your own custom event, you must create a [JSON schema][json-schema] for that event and upload it to an [Iglu Schema Repository][iglu-repo]. Ghct uses the schema to validate that the JSON containing the event properties is well-formed.

3.8.1 trackSelfDescribingEvent

To track a self-describing event, you make use the trackSelfDescribingEvent method:

window.ghct_name_here('trackSelfDescribingEvent', <<SELF-DESCRIBING EVENT JSON>>);

For example:

window.ghct_name_here('trackSelfDescribingEvent', {
      schema: 'iglu:com.acme_company/viewed_product/jsonschema/2-0-0',
      data: {
          productId: 'ASO01043',
          category: 'Dresses',
          brand: 'ACME',
          returning: true,
          price: 49.95,
          sizes: ['xs', 's', 'l', 'xl', 'xxl'],
          availableSince: new Date(2013,3,7)
      }
  });

The second argument is a [self-describing JSON][self-describing-jsons]. It has two fields:

  • A data field, containing the properties of the event
  • A schema field, containing the location of the [JSON schema][json-schema] against which the data field should be validated.

The data field should be flat, not nested.

trackSelfDescribingEvent can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

Back to top [Back to JavaScript technical documentation contents][contents]

Link click tracking is enabled using the enableLinkClickTracking method. Use this method once and the Tracker will add click event listeners to all link elements. Link clicks are tracked as unstructured events. Each link click event captures the link's href attribute. The event also has fields for the link's id, classes, and target (where the linked document is opened, such as a new tab or new window).

[Here][link-click-schema] is the JSON schema for a link click event.

3.9.1 enableLinkClickTracking

Turn on link click tracking like this:

window.ghct_name_here('enableLinkClickTracking');

This is its signature:

enableLinkClickTracking(filter, pseudoclicks, content);

You can control which links are tracked using the second argument. There are three ways to do this: a blacklist, a whitelist, and a filter function.

Blacklists

This is an array of CSS classes which should be ignored by link click tracking. For example, the below code will stop link click events firing for links with the class "barred" or "untracked", but will fire link click events for all other links:

window.ghct_name_here('enableLinkClickTracking', {'blacklist': ['barred', 'untracked']});

If there is only one class name you wish to blacklist, you don't need to put it in an array:

window.ghct_name_here('enableLinkClickTracking', {'blacklist': 'barred'});

Whitelists

The opposite of a blacklist. This is an array of the CSS classes of links which you do want to be tracked. Only clicks on links with a class in the list will be tracked.

window.ghct_name_here('enableLinkClickTracking', {'whitelist': ['unbarred', 'tracked']});

If there is only one class name you wish to whitelist, you don't need to put it in an array:

window.ghct_name_here('enableLinkClickTracking', {'whitelist': 'unbarred'});

Filter functions

You can provide a filter function which determines which links should be tracked. The function should take one argument, the link element, and return either 'true' (in which case clicks on the link will be tracked) or 'false' (in which case they won't).

The following code will track clicks on those and only those links whose id contains the string "interesting":

function myFilter (linkElement) {
    return linkElement.id.indexOf('interesting') > -1;
  }
  
  window.ghct_name_here('enableLinkClickTracking', {'filter': myFilter});

The second optional parameter is pseudoClicks. If this is not turned on, Firefox will not recognise middle clicks. If it is turned on, there is a small possibility of false positives (click events firing when they shouldn't). Turning this feature on is recommended:

window.ghct_name_here('enableLinkClickTracking', null, true);

The third optional parameter is content. Set it to true if you want link click events to capture the innerHTML of the clicked link:

window.ghct_name_here('enableLinkClickTracking', null, null, true);

The innerHTML of a link is all the text between the a tags. Note that if you use a base 64 encoded image as a link, the entire base 64 string will be included in the event.

Each link click event will include (if available) the destination URL, id, classes and target of the clicked link. (The target attribute of a link specifies a window or frame where the linked document will be loaded.)

enableLinkClickTracking can also be passed an array of custom contexts to attach to every link click event as an additional final parameter. See Contexts for more information.

3.9.2 refreshLinkClickTracking

enableLinkClickTracking only tracks clicks on links which exist when the page has loaded. If new links can be added to the page after then which you wish to track, just use refreshLinkClickTracking. This will add Ghct click listeners to all links which do not already have them (and which match the blacklist, whitelist, or filter function you specified when enableLinkClickTracking was originally called). Use it like this:

window.ghct_name_here('refreshLinkClickTracking');

3.9.3 trackLinkClick

You can manually track individual link click events with the trackLinkClick method. This is its signature:

function trackLinkClick(targetUrl, elementId, elementClasses, elementTarget, elementContent);

Of these arguments, only targetUrl is required. This is how to use trackLinkClick:

window.ghct_name_here('trackLinkClick', 'http://www.example.com', 'first-link', ['class-1', 'class-2'], '', 'this page');

trackLinkClick can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

Back to top [Back to JavaScript technical documentation contents][contents]

3.10 Form tracking

Ghct automatic form tracking detects two event types:

change_form

When a user changes the value of a textarea, input, or select element inside a form, a [ change_form][change_form] event will be fired. It will capture the name, type, and new value of the element, and the id of the parent form.

submit_form

When a user submits a form, a [ submit_form][submit_form] event will be fired. It will capture the id and classes of the form and the name, type, and value of all textarea, input, and select elements inside the form.

Note that this will only work if the original form submission event is actually fired. If you prevent it from firing, for example by using a jQuery event handler which returns false to handle clicks on the form's submission button, the Ghct submit_form event will not be fired.

3.10.1 enableFormTracking

Use the enableFormTracking method to add event listeners to turn on form tracking by adding event listeners to all form elements and to all interactive elements inside forms (that is, all input, textarea, and select elements).

window.ghct('enableFormTracking');

This will only work for form elements which exist when it is called. If you are creating a form programatically, call enableFormTracking again after adding it to the document to track it. (You can call enableFormTracking multiple times without risk of duplicated events.)

Note that events on password fields will not be tracked.

3.10.2 Custom form tracking

It may be that you do not want to track every field in a form, or every form on a page. You can customize form tracking by passing a configuration argument to the enableFormTracking method. This argument should be an object with two elements named "forms" and "fields". The "forms" element determines which forms will be tracked; the "fields" element determines which fields inside the tracked forms will be tracked. As with link click tracking, there are three ways to configure each field: a blacklist, a whitelist, or a filter function. You do not have to use the same method for both fields.

Blacklists

This is an array of strings used to prevent certain elements from being tracked. Any form with a CSS class in the array will be ignored. Any field whose name property is in the array will be ignored. All other elements will be tracked.

Whitelists

This is an array of strings used to turn on certail. Any form with a CSS class in the array will be tracked. Any field in a tracked form whose name property is in the array will be tracked. All other elements will be ignored.

Filter functions

This is a function used to determine which elements are tracked. The element is passed as the argument to the function and is tracked if and only if the value returned by the function is truthy.

Examples

To track every form element and every field except those fields named "password":

var config = {
    forms: {
      blacklist: []
    },
    fields: {
      blacklist: ['password']
    }
  };
  
  window.ghct('enableFormTracking', config);

To track only the forms with CSS class "tracked", and only those fields whose ID is not "private":

var config = {
    forms: {
      whitelist: ["tracked"]
    },
    fields: {
      filter: function (elt) {
        return elt.id !== "private";
      }
    }
  };
  
  window.ghct('enableFormTracking', config);

3.11 trackAddToCart and trackRemoveFromCart

These methods let you track users adding and removing items from a cart on an ecommerce site. Their arguments are identical:

Name Required? Description Type
sku Yes Item SKU string
name No Item name string
category No Item category string
unitPrice Yes Item price number
quantity Yes Quantity added to or removed from cart number
currency No Item price currency string

An example:

window.ghct_name_here('trackAddToCart', '000345', 'blue tie', 'clothing', 3.49, 2, 'GBP');
  window.ghct_name_here('trackRemoveFromCart', '000345', 'blue tie', 'clothing', 3.49, 1, 'GBP');

Both methods are implemented as Ghct unstructured events. You can see schemas for the [ add_to_cart][add_to_cart] and [ remove_from_cart][remove_from_cart] events.

Both methods can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

3.12 trackSiteSearch

Use the trackSiteSearch method to track users searching your website. Here are its arguments:

Name Required? Description Type
terms Yes Search terms array
filters No Search filters JSON
totalResults No Results found number
pageResults No Results displayed on first page number

An example:

window.ghct_name_here('trackSiteSearch',
      ['unified', 'log'],      // search terms
      {'category': 'books', 'sub-category': 'non-fiction'},  // filters
      14,                      // results found
      8                        // results displayed on first page
  );

Site search events are implemented as Ghct unstructured events. [Here][site_search] is the schema for a site_search event.

trackSiteSearch can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

3.13 trackTiming

Use the trackTiming method to track user timing events such as how long resources take to load. Here are its arguments:

Name Required? Description Type
category Yes Timing category string
variable Yes Timed variable string
timing Yes Number of milliseconds elapsed number
label No Label for the event string

An example:

window.ghct('trackTiming',
    'load',            // Category of the timing variable
    'map_loaded',      // Variable being recorded
    50,                // Milliseconds taken
    'Map loading time' // Optional label
  );

Site search events are implemented as Ghct unstructured events. [Here][timing] is the schema for a timing event.

trackTiming can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

3.14 Enhanced Ecommerce tracking

For more information on the Enhanced Ecommerce functions please see the Google Analytics documentation.

3.14.1 addEnhancedEcommerceActionContext

Use the addEnhancedEcommerceActionContext method to add a GA Enhanced Ecommerce Action Context to the Tracker:

Name Required? Type
id Yes string
affiliation No string
revenue No number OR string
tax No number OR string
shipping No number OR string
coupon No string
list No string
step No integer OR string
option No string
currency No string

Adding an action using Google Analytics:

ga('ec:setAction', 'purchase', {
    'id': 'T12345',
    'affiliation': 'Google Store - Online',
    'revenue': '37.39',
    'tax': '2.85',
    'shipping': '5.34',
    'coupon': 'SUMMER2013'
  });

NOTE: The action type is passed with the action context in the Google Analytics example. We have seperated this by asking you to call the trackEnhancedEcommerceAction function to actually send the context and the action.

Adding an action using Ghct:

window.ghct('addEnhancedEcommerceActionContext',
    'T12345', // The Transaction ID
    'Google Store - Online', // The affiliate
    '37.39', // The revenue
    '2.85', // The tax
    '5.34', // The shipping
    'WINTER2016' // The coupon
  );

3.14.2 addEnhancedEcommerceImpressionContext

Use the addEnhancedEcommerceImpressionContext method to add a GA Enhanced Ecommerce Impression Context to the Tracker:

Name Required? Type
id Yes string
name No string
list No string
brand No string
category No string
variant No string
position No integer OR string
price No number OR string
currency No string

Adding an impression using Google Analytics:

ga('ec:addImpression', {
    'id': 'P12345',
    'name': 'Android Warhol T-Shirt',
    'list': 'Search Results',
    'brand': 'Google',
    'category': 'Apparel/T-Shirts',
    'variant': 'Black',
    'position': 1
  });

Adding an impression using Ghct:

window.ghct('addEnhancedEcommerceImpressionContext',
    'P12345', // The ID
    'Android Warhol T-Shirt', // The name
    'Search Results', // The list
    'Google', // The brand
    'Apparel/T-Shirts', // The category
    'Black', // The variant
    '1' // The position
  );

3.14.3 addEnhancedEcommerceProductContext

Use the addEnhancedEcommerceProductContext method to add a GA Enhanced Ecommerce Product Field Context:

Name Required? Type
id Yes string
name No string
list No string
brand No string
category No string
variant No string
price No number OR string
quantity No integer OR string
coupon No string
position No integer OR string
currency No string

Adding a product using Google Analytics:

ga('ec:addProduct', {
    'id': 'P12345',
    'name': 'Android Warhol T-Shirt',
    'brand': 'Google',
    'category': 'Apparel/T-Shirts',
    'variant': 'Black',
    'position': 1
  });

Adding a product using Ghct:

window.ghct('addEnhancedEcommerceProductContext',
    'P12345', // The ID
    'Android Warhol T-Shirt', // The name
    'Search Results', // The list
    'Google', // The brand
    'Apparel/T-Shirts', // The category
    'Black', // The variant
    1 // The quantity
  );

3.14.4 addEnhancedEcommercePromoContext

Use the addEnhancedEcommercePromoContext method to add a GA Enhanced Ecommerce Promotion Field Context:

Name Required? Type
id Yes string
name No string
creative No string
position No string
currency No string

Adding a promotion using Google Analytics:

ga('ec:addPromo', {
    'id': 'PROMO_1234',
    'name': 'Summer Sale',
    'creative': 'summer_banner2',
    'position': 'banner_slot1'
  });

Adding a promotion using ghct:

window.ghct('addEnhancedEcommercePromoContext',
    'PROMO_1234', // The Promotion ID
    'Summer Sale', // The name
    'summer_banner2', // The name of the creative
    'banner_slot1' // The position
  );

3.14.5 trackEnhancedEcommerceAction

Use the trackEnhancedEcommerceAction method to track a GA Enhanced Ecommerce Action. When this function is called all of the added Ecommerce Contexts are attached to this action and flushed from the Tracker.

Name Required? Type
action Yes string

The allowed actions:

  • click
  • detail
  • add
  • remove
  • checkout
  • checkout_option
  • purchase
  • refund
  • promo_click
  • view

Adding an action using Google Analytics:

ga('ec:setAction', 'refund', {
    'id': 'T12345'
  });

Adding an action using Ghct:

window.ghct('addEnhancedEcommerceActionContext',
    'T12345' // ID
  );
  window.ghct('trackEnhancedEcommerceAction',
    'refund'
  );

3.15 Custom contexts

Custom contexts can be used to augment any standard Ghct event type, including unstructured events, with additional data.

Custom contexts can be added as an extra argument to any of Ghct's track..() methods and to addItem and addTrans.

Each custom context is a self-describing JSON following the same pattern as an unstructured event. As with unstructured events, if you want to create your own custom context, you must create a [JSON schema][json-schema] for it and upload it to an [Iglu repository][iglu-repo]. Since more than one (of either different or the same type) can be attached to an event, the context argument (if it is provided at all) should be a non-empty array of self-describing JSONs.

Important: Even if only one custom context is being attached to an event, it still needs to be wrapped in an array.

Here are two example custom context JSONs. One describes a page, and the other describes a user on that page.

{
      schema: "iglu:com.example_company/page/jsonschema/1-2-1",
      data: {
          pageType: 'test',
          lastUpdated: new Date(2014,1,26)
      }
  }
{
      schema: "iglu:com.example_company/user/jsonschema/2-0-0",
      data: {
        userType: 'tester'
      }
  }

How to track a page view with both these contexts attached:

window.ghct_name_here('trackPageView', null, [{
      schema: "iglu:com.example_company/page/jsonschema/1-2-1",
      data: {
          pageType: 'test',
          lastUpdated: new Date(2014,1,26)
      }
  },
  {
      schema: "iglu:com.example_company/user/jsonschema/2-0-0",
      data: {
        userType: 'tester'
      }
  }]);

In this case an empty string has been provided to the optional customTitle argument in order to reach the context argument.

For more information on custom contexts, see [this][contexts] blog post.

3.16 Error tracking

Note that this is only available on version 2.7.0 and above of the JS tracker.

Ghct JS tracker provides two ways of tracking exceptions: manual tracking of handled exceptions using trackError and automatic tracking of unhandled exceptions using enableErrorTracking.

3.16.1 trackError

Use the trackError method to track handled exceptions (application errors) in your JS code. This is its signature:

function (message, filename, lineno, colno, error, contexts)
Name Required? Description Type
message Yes Error message string
filename No Filename or URL string
lineno No Line number of problem code chunk number
colno No Column number of problem code chunk number
error No JS ErrorEvent ErrorEvent

Of these arguments, only message is required. Signature of this method defined to match window.onerror callback in modern browsers.

try {
    var user = getUser()
  } catch(e) {
    window.ghct_name_here('trackError', 'Cannot get user object', 'shop.js', null, null, e);
  }

trackError can also be passed an array of custom contexts as an additional final parameter. See Contexts for more information.

Using trackError it's assumed that developer knows where error could happen, which is not often the case. Therefor it's recommended to use enableErrorTracking as it allows you to discover errors that weren't expected.

3.16.2 enableErrorTracking

Use the enableErrorTracking method to track unhandled exceptions (application errors) in your JS code. This is its signature:

function (filter, contextAdder)
Name Required? Description Type
filter No Predicate function to filter exceptions Function ErrorEvent => Boolean
contextAdder No Function to grab custom contexts Function ErrorEvent => Array

Unlike trackError you need enable error tracking only once:

window.ghct_name_here('enableErrorTracking')

Application error events are implemented as Ghct unstructured events. [Here][application_error] is the schema for a application_error event.

Back to top [Back to JavaScript technical documentation contents][contents]

3.17 Setting the true timestamp

As standard, every event tracked by the Javascript tracker will be recorded with two timestamps:

  1. A device_created_tstamp - set when the event occurred
  2. A device_sent_tstamp - set when the event was sent by the tracker to the collector

These are combined downstream in the Ghct pipeline (with the collector_tstamp) to calculate the derived_tstamp, which is our best estimate of when the event actually occurred.

In certain circumstances you might want to set the timestamp yourself e.g. if the JS tracker is being used to process historical event data, rather than tracking the events live. In this case you can set the true_timestamp for the event. When set, this will be used as the value in the derived_tstamp rather than a combination of the device_created_tstamp, device_sent_tstamp and collector_tstamp.

To set the true timestamp add an extra argument to your track method:

{type: 'ttm', value: unixtimestamp}

e.g. to set a true timestamp with a page view event:

window.ghct_name_here('trackPageView', null, [{
      schema: "iglu:com.example_company/page/jsonschema/1-2-1",
      data: {
          pageType: 'test',
          lastUpdated: new Date(2014,1,26)
      }
  },
  {
      schema: "iglu:com.example_company/user/jsonschema/2-0-0",
      data: {
        userType: 'tester'
      }
  }],
  {type: 'ttm', value: 1482511723});

e.g. to set a true timestamp for a self-describing event:

window.ghct_name_here('trackSelfDescribingEvent', {
      schema: 'iglu:com.acme_company/viewed_product/jsonschema/2-0-0',
      data: {
          productId: 'ASO01043',
          category: 'Dresses',
          brand: 'ACME',
          returning: true,
          price: 49.95,
          sizes: ['xs', 's', 'l', 'xl', 'xxl'],
          availableSince: new Date(2013,3,7)
      }
  }, null, {type: 'ttm', value: 1482511723});

Back to top

2. General parameters

2.1 Loading Ghct.js

Use the following tag to your page to load Ghct.js:

<script type="text/javascript" async=1>
  ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalGhctNamespace=p.GlobalGhctNamespace||[];
  p.GlobalGhctNamespace.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","//developer.goodharvest.co/ghct.js","ghct_name_here"));
  </script>

Important note regarding testing: "//developer.goodharvest.co/ghct.js" is the protocol-relative URL used to fetch ghct.js. It will work if the your web page is using the "http" or "https" protocol. But if you are testing locally and loading your page from your filesystem using the "file" protocol (so its URI looks something like "file:///home/joe/ghct_test.html"), the protocol-relative URL will also use that protocol, preventing the script from loading. To avoid this, change the URL to "http://developer.goodharvest.co/ghct.js" when testing locally.

As well as loading Ghct, this tag creates a global function called "ghct_name_here" which you use to access the Tracker. You can replace the string "ghct_name_here" with the function name of your choice. This is encouraged: if there are two Ghct users on the same page, there won't be any conflict between them as long as they have chosen different function names. The rest of the documentation will assume that the function is called "ghct_name_here".

Once the function ghct_name_here is created, the syntax for using Ghct methods is as follows:

window.ghct_name_here({{"methodName"}}, {{first method argument}}, {{second method argument}}, ...);

For example, the method trackStructEvent has this signature:

function trackStructEvent(category, action, label, property, value, context)

where only the first two arguments are required. You would use it like this:

window.ghct_name_here('trackStructEvent', 'Mixes', 'Play', '', '', 20);

Empty strings are provided for the label and property arguments to pad them out. ( Null would also work.) They won't be added to the event. Neither will the context argument, which isn't provided at all.

Back to top [Back to JavaScript technical documentation contents][contents]

2.2 Initialising a tracker

Tracker initialization is indicated with the "newTracker" string and takes three arguments:

  1. The tracker namespace
  2. The collector endpoint
  3. An optional argmap containing other settings

Here is a simple example of how to initialise a tracker:

ghct_name_here("newTracker", "cf", "d3rkrsqld9gmqf.cloudfront.net", {
    appId: "cfe23a",
    platform: "mob"
  });

The tracker will be named "cf" and will send events to d3rkrsqld9gmqf.cloudfront.net, the cloudfront collector specified. The final argument is called the argmap. Here it is just used to set the app ID and platform for the tracker. Each event the tracker sends will have an app ID field set to "cfe23a" and a platform field set to "mob".

Here is a longer example in which every tracker configuration parameter is set:

ghct_name_here("newTracker", "cf", "d3rkrsqld9gmqf.cloudfront.net", {
    appId: "cfe23a",
    platform: "mob"
    cookieDomain: null,
    discoverRootDomain: true,
    cookieName: "_sp534_",
    encodeBase64: false,
    respectDoNotTrack: false,
    userFingerprint: true,
    userFingerprintSeed: 6385926734,
    pageUnloadTimer: 0,
    forceSecureTracker: true,
    post: true,
    bufferSize: 5,
    maxPostBytes: 45000,
    crossDomainLinker: function (linkElement) {
      return (linkElement.href === "http://acme.de" || linkElement.id === "crossDomainLink");
    },
    cookieLifetime: 86400 * 31,
    stateStorageStrategy: "cookie",
    contexts: {
      webPage: true,
      performanceTiming: true,
      gaCookies: true,
      geolocation: false
    }
  });

We will now go through the various argmap parameters. Note that these are all optional. In fact, you aren't required to provide any argmap at all.

2.2.1 Setting the application ID

Set the application ID using the appId field of the argmap. This will be attached to every event the tracker fires. You can set different application IDs on different parts of your site. You can then distinguish events that occur on different applications by grouping results based on application_id.

2.2.2 Setting the platform

Set the application platform using the platform field of the argmap. This will be attached to every event the tracker fires. Its default value is "web". For a list of supported platforms, please see the [Ghct Tracker Protocol][ghct-tracker-protocol].

If your website spans multiple subdomains e.g.

You will want to track user behaviour across all those subdomains, rather than within each individually. As a result, it is important that the domain for your first party cookies is set to '.mysite.com' rather than ' www.mysite.com'. By doing so, any values that are stored on the cookie on one of subdomain will be accessible on all the others.

It is recommended that you enable automatic discovery and setting of the root domain.

Otherwise, set the cookie domain for the tracker instance using the cookieDomain field of the argmap. If this field is not set, the cookies will not be given a domain.

WARNING: Changing the cookie domain will reset all existing cookies. As a result, it might be a major one-time disruption to data analytics because all visitors to the website will receive a new domain_userid.

Set the cookie name for the tracker instance using the cookieName field of the argmap. The default is " sp". Ghct uses two cookies, a domain cookie and a session cookie. In the default case, their names are " spid" and " spses" respectively. If you are upgrading from an earlier version of Ghct, you should use the default cookie name so that the cookies set by the earlier version are still remembered. Otherwise you should provide a new name to prevent clashes with other Ghct users on the same page.

Once set, you can retrieve a cookie name thanks to the getCookieName(basename) method where basename is id or ses for the domain and session cookie respectively. As an example, you can retrieve the complete name of the domain cookie with getCookieName('id').

2.2.5 Configuring base 64 encoding

By default, self-describing events and custom contexts are encoded into Base64 to ensure that no data is lost or corrupted. You can turn encoding on or off using the encodeBase64 field of the argmap.

2.2.6 Respecting Do Not Track

Most browsers have a Do Not Track option which allows users to express a preference not to be tracked. You can respect that preference by setting the respectDoNotTrack field of the argmap to true. This prevents cookies from being sent and events from being fired.

It is possible to set an opt-out cookie in order not to track anything similarly to Do Not Track through setOptOutCookie(cookieName). If this cookie is set, cookies won't be stored and events won't be fired.

2.2.8 User fingerprinting

By default, the tracker generates a user fingerprint based on various browser features. This fingerprint is likely to be unique and so can be used to track anonymous users. You can turn user fingerprinting off by setting the userFingerprint field of the argmap to false.

2.2.9 Setting the user fingerprint seed

The userFingerprintSeed field of the the argmap lets you choose the hash seed used to generate the user fingerprint. If this is not specified, the default is 123412414.

2.2.10 Setting the page unload pause

Whenever the Ghct Javascript Tracker fires an event, it automatically starts a 500 millisecond timer running. If the user clicks on a link or refreshes the page during this period (or, more likely, if the event was triggered by the user clicking a link), the page will wait until either the event is sent or the timer is finished before unloading. 500 milliseconds is usually enough to ensure the event has time to be sent.

You can change the pause length (in milliseconds) using the pageUnloadTimer of the argmap. The above example completely eliminates the pause. This does make it unlikely that events triggered by link clicks will be sent.

See also How the Tracker uses localStorage for an explanation of how the tracker can later recover and send unsent events.

2.2.11 Setting the event request protocol

Normally the protocol (http or https) used by the Tracker to send events to a collector is the same as the protocol of the current page. You can force it to use https by setting the forceSecureTracker field of the argmap to true.

2.2.12 Setting an unsecure event request protocol

Normally the protocol (http or https) used by the Tracker to send events to a collector is the same as the protocol of the current page. You can force it to use http by setting the forceUnsecureTracker field of the argmap to true. If forceSecureTracker is activated this argument is ignored.

NOTE: This argument should only be used for testing purposes as it creates security vulnerabilities.

Whenever an event fires, the Tracker creates a session cookie. If the cookie didn't previously exist, the Tracker interprets this as the start of a new session.

By default the session cookie expires after 30 minutes. This means that a user leaving the site and returning in under 30 minutes does not change the session. You can override this default by setting sessionCookieTimeout to a duration (in seconds) in the argmap. For example,

{
    ...
    sessionCookieTimeout: 3600
    ...
  }

would set the session cookie lifespan to an hour.

2.2.14 Configuring the storage strategy

Three strategies are made available to store the Tracker's state: cookies, local storage or no storage at all. You can set the strategy with the help of the stateStorageStrategy parameter in the argmap to "cookie" (the default), "localStorage" or "none" respectively.

When choosing local storage, the Tracker will additionally store events in local storage before sending them so that they can be recovered if the user leaves the page before they are sent.

2.2.15 Adding predefined contexts

The JavaScript Tracker comes with many predefined contexts which you can automatically add to every event you send. To enable them, simply add them to the contexts field of the argmap as above.

2.2.15.1 webPage context

When the JavaScript Tracker loads on a page, it generates a new page view UUID. If the webPage context is enabled, then a context containing this UUID is attached to every page view.

2.2.15.2 performanceTiming context

If this context is enabled, the JavaScript Tracker will use the create a context JSON from the window.performance.timing object, along with the Chrome firstPaintTime field (renamed to "chromeFirstPaint") if it exists. This data can be used to calculate page performance metrics.

Note that if you fire a page view event as soon as the page loads, the domComplete, loadEventStart, loadEventEnd, and chromeFirstPaint metrics in the Navigation Timing API may be set to zero. This is because those properties are only known once all scripts on the page have finished executing. Additionally the redirectStart, redirectEnd, and secureConnectionStart are set to 0 if there is no redirect or a secure connection is not requested.

For more information on the Navigation Timing API, see [the specification][performance-spec].

2.2.15.3 gaCookies context

If this context is enabled, the JavaScript Tracker will look for Google Analytics cookies (specifically the " utma", "utmb", " utmc", "utmv", " _utmz", and "ga" cookies) and combine their values into a JSON which gets sent with every event.

2.2.15.4 geolocation context

If this context is enabled, the JavaScript Tracker will attempt to create a context from the visitor's geolocation information. If the visitor has not already given or denied the website permission to use their geolocation information, a prompt will appear. If they give permission, then all events from that moment on will include their geolocation information.

For more information on the geolocation API, see [the specification][geolocation-spec].

2.2.15.5 augurIdentityLite context

If this context is enabled the JavaScript Tracker will use the window['augur'] object to create a context JSON.

To see what will be captured please see the JsonSchema file io.augur.ghct/identity_lite/jsonschema/1-0-0.

2.2.15.6 optimizelyExperiments context

If this context is enabled the JavaScript Tracker will use the window['optimizely'].data.experiments object to create an array of context JSONs; one for each sub-object.

To see what will be captured please see the JsonSchema file com.optimizely/experiment/jsonschema/1-0-0.

2.2.15.7 optimizelyStates context

If this context is enabled the JavaScript Tracker will use the window['optimizely'].data.state object to create an array of context JSONs; one for each sub-object.

To see what will be captured please see the JsonSchema file com.optimizely/state/jsonschema/1-0-0.

2.2.15.8 optimizelyVariations context

If this context is enabled the JavaScript Tracker will use the window['optimizely'].data.variations object to create an array of context JSONs; one for each sub-object.

To see what will be captured please see the JsonSchema file com.optimizely/variation/jsonschema/1-0-0.

2.2.15.9 optimizelyVisitor context

If this context is enabled the JavaScript Tracker will use the window['optimizely'].data.visitor object to create a context JSON.

To see what will be captured please see the JsonSchema file com.optimizely/visitor/jsonschema/1-0-0.

2.2.15.10 optimizelyAudiences context

If this context is enabled the JavaScript Tracker will use the window['optimizely'].data.visitor.audiences object to create an array of context JSONs; one for each sub-object.

To see what will be captured please see the JsonSchema file com.optimizely/visitor_audience/jsonschema/1-0-0.

2.2.15.11 optimizelyDimensions context

If this context is enabled the JavaScript Tracker will use the window['optimizely'].data.visitor.dimensions object to create an array of context JSONs; one for each sub-object.

To see what will be captured please see the JsonSchema file com.optimizely/visitor_dimension/jsonschema/1-0-0.

2.2.15.12 optimizelySummary context

Unlike previously mentioned Optimizely contexts this context doesn't attach existing in browser object, but constructs its own using only data necessary to join with [exported Optimizely][optimizely-export] data.

To see what will be captured please see the JsonSchema file com.optimizely.ghct/optimizely_summary/jsonschema/1-0-0.

We highly recommend to use this context instead of previous ones because it is has much smaller footprint and contains all necessary data.

2.2.15.13 optimizelyXSummary context

Support for OptimizelyX has been introduced in the tracker, you can have a look at the JsonSchema in com.optimizely/optimizelyx_summary/jsonschema/1-0-0 to see what is being captured.

If you're planning on leveraging the context's variation names, you'll have to untick 'Mask descriptive names in project code and third-party integrations' in the OptimizelyX menu -> Settings -> Privacy. Otherwise, all variation names will be null.

2.2.15.14 parrable context

If this context is enabled, the JavaScript Tracker will use the window['_hawk'] object to create a Parrable context JSON.

To see what will captured, please see the JsonSchema file com.parrable/encrypted_payload/jsonschema/1-0-0.

2.2.16 POST support

If you set the post field of the argmap to true, the tracker will send events using POST requests rather than GET requests. In browsers such as Internet Explorer 9 which do not support cross-origin XMLHttpRequests, the tracker will fall back to using GET.

The main advantage of POST requests is that they circumvent Internet Explorer's maximum URL length of 2083 characters by storing the event data in the body of the request rather than the querystring.

The [Clojure Collector][clojure-collector] and [Scala Stream Collector][ssc] accept events sent by POST; the [Cloudfront Collector][cloudfront-collector] does not..

You can also batch events sent by POST by setting a numeric bufferSize field in the argmap. This is the number of events to buffer before sending them all in a single POST. If the user navigates away from the page while the buffer is only partially full, the tracker will attempt to send all stored events immediately, but this often doesn't happen before the page unloads. Normally the tracker will store unsent events in localStorage, meaning that unsent events will be resent when the user next visits a page on the same domain. The bufferSize defaults to 1, meaning events are sent as soon as they are created.

If you have set bufferSize to greater than 1, you can flush the buffer using the flushBuffer method:

ghct("flushBuffer");

For instance, if you wish to send several events at once, you might make the API calls to create the events and store them and then and call flushBuffer afterwards to ensure they are all sent before the user leaves the page.

Note that if localStorage is inaccessible or you are not using it to store data, the buffer size will always be 1 to prevent losing events when the user leaves the page.

2.2.17 Configuring cross-domain tracking

The JavaScript Tracker can add an additional parameter named " sp" to the querystring of outbound links. Its value includes the domain user ID for the current page and the time at which the link was clicked. This makes these values visible in the "url" field of events sent by an instance of the JavaScript Tracker on the destination page. The enrichment process will use these values to populate the `refrdomain_userid andrefr_dvce_tstamp` fields in Redshift for all events fired on the destination page.

You can configure which links get decorated this way using the crossDomainLinker field of the argmap. This field should be a function taking one argument (the link element) and return true if the link element should be decorated and false otherwise. For example, this function would only decorate those links whose destination is " http://acme.de" or whose HTML id is "crossDomainLink":

{
    crossDomainLinker: function (linkElement) {
      return (linkElement.href === "http://acme.de" || linkElement.id === "crossDomainLink");
    }
  }

If you want to decorate every link to the domain github.com:

{
    crossDomainLinker: function (linkElement) {
      return /^https:\/\/github\.com/.test(linkElement.href);
    }
  }

If you want to decorate every link, regardless of its destination:

{
    crossDomainLinker: function (linkElement) {
      return true;
    }
  }

Note that the above will decorate "links" which are actually just JavaScript actions (with an href of "javascript:void(0)"). To exclude these links:

window.ghct('crossDomainLinker', function(linkElement) {
    return linkElement.href.indexOf('javascript:') < 0;
  });

Note that when the tracker loads, it does not immediately decorate links. Instead it adds event listeners to links which decorate them as soon as a user clicks on them or navigates to them using the keyboard. This ensures that the timestamp added to the querystring is fresh.

If further links get added to the page after the tracker has loaded, you can use the tracker's crossDomainLinker method to add listeners again. (Listeners won't be added to links which already have them.)

ghct_name_here('crossDomainLinker', function () {
    return (linkElement.href === "http://acme.de" || linkElement.id === "crossDomainLink");
  });

Warning: If you enable link decoration, you should also make sure that at least one event is fired on the page. Firing an event causes the tracker to write the domain_userid to a cookie. If the cookie doesn't exist when the user leaves the page, the tracker will generate a new ID for them when they return rather than keeping the old ID.

2.2.18 Configuring the maximum payload size in bytes

Because the Clojure Collector and the Scala Stream Collector both have a maximum request size, the Tracker limits POST requests to 40000 bytes. If the combined size of the events in localStorage is greater than this limit, they will be split into multiple POST requests. You can override this default using a maxPostBytes in the argmap.

The Clojure Collector can't handle requests bigger than 64kB. The Scala Stream Collector cannot process requests bigger than 50kB because that is the maximum size of a Kinesis record.

2.2.19 Automatically discover and set the root domain

If the optional discoverRootDomain field of the argmap is set to true, the Tracker automatically discovers and sets the configCookieDomain value to the root domain.

NOTE: If you have been setting this manually please note that the automatic detection does not prepend a '.' to the domain. For example a root domain of ".mydomain.com" would become "mydomain.com". This is because the library we use for setting cookies doesn't care about the difference.

This will then result in a different domain hash, so we recommend that if you have been setting this manually with a leading '.' to continue to do so manually.

2.2.20 Configuring the cookies lifetime

Whenever tracker initialized on your domain - it will set domain-specific visitor's cookies. By default, these cookies will be active for 2 years. You can change this duration using cookieLifetime argmap parameter or setVisitorCookieTimeout method.

ghct_name_here("newTracker", "cf", "d3rkrsqld9gmqf.cloudfront.net", {
    cookieLifetime: 86400 * 31,
  });
  
  // or
  
  ghct_name_here('setVisitorCookieTimeout', 86400 * 30);  // 30 days

If cookieLifetime is set to 0, the cookie will expire at the end of the session (when the browser closes). If set to -1, the first-party cookies will be disabled.

2.2.21 Tracking prerendered pages

Some browsers can "preload" pages while user typing URL in. These users not always end up in that page, however due page preloading tracker is initialized and loaded.

JS Tracker by default doesn't fire events when page is preloaded, but sets callback on visibilitychange event, which fires actual event only when page starts to render.

To explicitly enable tracking for prerendered pages you can use setCountPreRendered function:

ghct_name_here("setCountPreRendered", true);

Back to top [Back to JavaScript technical documentation contents][contents]

2.3 Other parameters

2.3.1 Setting the user ID

The JavaScript Tracker automatically sets a domain_userid based on a first party cookie.

There are many situations, however, when you will want to identify a specific user using an ID generated by one of your business systems. To do this, you use one of the methods described in this section: setUserId, setUserIdFromLocation, setUserIdFromReferrer, and setUserIdFromCookie.

Typically, companies do this at points in the customer journey when the user identifies him / herself e.g. if he / she logs in.

Note: this will only set the user ID on further events fired while the user is on this page; if you want events on another page to record this user ID too, you must call setUserId on the other page as well.

2.3.1.1 setUserId

setUserId is the simplest of the four methods. It sets the business user ID to a string of your choice:

ghct_name_here('setUserId', 'joe.blogs@email.com');
2.3.1.2 setUserIdFromLocation

setUserIdFromLocation lets you set the user ID based on a querystring field of your choice. For example, if the URL is http://www.mysite.com/home?id=user345, then the following code would set the user ID to "user345":

ghct_name_here('setUserIdFromLocation', 'id');
2.3.1.3 setUserIdFromReferrer

setUserIdFromReferrer functions in the same way as setUserIdFromLocation, except that it uses the referrer querystring rather than the querystring of the current page.

ghct_name_here('setUserIdFromReferrer', 'id');
2.3.1.4 setUserIdFromCookie

Use setUserIdFromCookie to set the value of a cookie as the user ID. For example, if you have a cookie called "cookieid" whose value is "user123", the following code would set the user ID to "user123":

ghct_name_here('setUserIdFromCookie', 'cookieid');

Back to top [Back to JavaScript technical documentation contents][contents]

2.3.2 Setting a custom page URL and referrer URL

The Ghct JavaScript Tracker automatically tracks the page URL and referrerURL on any event tracked. However, in certain situations, you may want to override the one or both of these URLs with a custom value. (For example, this might be desirable if your CMS spits out particularly ugly URLs that are hard to unpick at analysis time.)

To set a custom page URL, use the setCustomUrl method:

ghct_name_here('setCustomUrl', 'http://mysite.com/checkout-page');

To set a custom referrer, use the setReferrerUrl method:

ghct_name_here('setReferrerUrl', 'http://custom-referrer.com');

On a single-page app, the page URL might change without the page being reloaded. Whenever an event is fired, the Tracker checks whether the page URL has changed since the last event. If it has, the page URL is updated and the URL at the time of the last event is used as the referrer. If you use setCustomUrl, the page URL will no longer be updated in this way. If you use setReferrerUrl, the referrer URL will no longer be updated in this way.

If you want to ensure that the original referrer is preserved even though your page URL can change without the page being reloaded, use setReferrerUrl like this before sending any events:

ghct_name_here('setReferrerUrl', document.referrer);

Back to top [Back to JavaScript technical documentation contents][contents]

2.4 Setting onload callbacks

If you call ghct_name_here with a function as the argument, the function will be executed when ghct.js loads:

ghct_name_here(function () {
    console.log("ghct.js has loaded");
  });

Or equivalently:

ghct_name_here(function (x) {
    console.log(x);
  }, "ghct.js has loaded");

The callback function should not be a method:

// TypeError: Illegal invocation
  ghct_name_here(console.log, "ghct.js has loaded");

will not work, because the value of this in the console.log function will be window rather than console.

You can get around this problem using Function.prototoype.bind as follows:

ghct_name_here(console.log.bind(console), "ghct.js has loaded");

2.5 Managing multiple trackers

You have more than one tracker instance running on the same page at once. This may be useful if you want to log events to different collectors. By default, any ghct method you call will be executed by every tracker you have created so far:

ghct_name_here("newTracker", "cf1", "d3rkrsqld9gmqf.cloudfront.net", {
    appId: "cfe23a",
    platform: "mob"
  });
  
  ghct_name_here("newTracker", "cf2", "a5grvrhue7ewvt.cloudfront.net", {
    appId: "cfe23a",
    platform: "mob"
  });
  
  // Both trackers will use this custom title
  ghct_name_here('setCustomUrl', 'http://mysite.com/checkout-page');
  
  // Both trackers will fire a structured event
  ghct_name_here('trackStructEvent', 'Mixes', 'Play', 'MrC/fabric-0503-mix', '', '0.0');

You can override this behaviour and specify which trackers will execute a Ghct method. To do this, change the method name by adding a colon followed by a list of tracker names separated by semicolons:

// Only the first tracker will fire this structured event
  ghct_name_here('trackStructEvent:cf1', 'Mixes', 'Play', 'MrC/fabric-0503-mix', '', '0.0');
  
  // Only the second tracker will fire this self-describing event
  ghct_name_here('trackSelfDescribingEvent:cf2', 'com.acme_company' 'Viewed Product',
      {
          product_id: 'ASO01043',
          category: 'Dresses',
          brand: 'ACME',
          returning: true,
          price: 49.95,
          sizes: ['xs', 's', 'l', 'xl', 'xxl'],
          available_since$dt: new Date(2013,3,7)
      }
  );
  
  // Both trackers will fire a page view event
  ghct_name_here('trackPageView:cf1;cf2');

2.6 How the Tracker stores state

Unless you have enabled respectDoNotTrack in the configuration argmap, the tracker will persist information on the client. The location depends on the stateStorageStrategy field in the argmap. By default, information will be stored in cookie. Alternatively, you can specify "localStorage" to have the state stored in local storage. Finally, you can set stateStorageStrategy to none in order not to store anything client side.

The stored state takes the form of two first party cookies: the session cookie and the ID cookie. By default their names are prefixed with " sp", but you can change this using the "cookieName" field in the argmap. Their names are suffixed with a hash of the current domain, so the full cookie names might look something like spses.4209 and spid.4209.

Called spses.{{DOMAIN HASH}} by default, the only purpose of this cookie is to differentiate between different visits. Whenever an event is fired, the session cookie is set to expire in 30 minutes. (This value can be altered using setSessionCookieTimeout.)

If no session cookie is already present when an event fires, the tracker treats this as an indication that long enough has passed since the user last visited that this session should be treated as a new session rather than a continuation of the previous session. The visitCount (how many times the user has visited) is increased by one and the lastVisitTs (the timestamp for the last session) is updated.

This cookie is called spid.{{DOMAIN HASH}} by default. It is used to persist information about a user's activity on the domain between sessions. It contains the following information:

  • An ID for the user based on a hash of various browser attributes
  • How many times the user has visited the domain
  • The timestamp of the user's first visit
  • The timestamp of the current visit
  • The timestamp of the last visit
  • The ID of the current session

It expires after 2 years.

There is a third sort of Ghct-related cookie: the cookie set by the [Clojure Collector][clojure-collector], independently of the JavaScript Tracker. If you are using another type of collector, this cookie will not be set. The Clojure Collector cookie is called "sp". It is a third-party cookie used to track users over multiple domains. It expires after one year.

You can use the following function to extract the user ID from the ID cookie:

/*
  * Function to extract the Ghct user ID from the first-party cookie set by the Ghct JavaScript Tracker
  *
  * @param string cookieName (optional) The value used for "cookieName" in the tracker constructor argmap
  * (leave blank if you did not set a custom cookie name)
  *
  * @return string or bool The ID string if the cookie exists or false if the cookie has not been set yet
  */
  function getGhctDuid(cookieName) {
    cookieName = cookieName || '_sp_';
    var matcher = new RegExp(cookieName + 'id\\.[a-f0-9]+=([^;]+);?');
    var match = document.cookie.match(matcher);
    if (match && match[1]) {
      return match[1].split('.')[0];
    } else {
      return false;
    }
  }

If you set a custom cookieName field in the argmap, pass that name into the function; otherwise call the function without arguments. Note that if the function is called before the cookie exists (i.e. when the user is visiting the page for the first time and ghct.js has not yet loaded) if will return false.

2.8 Optional timestamp argument

Since 2.7.0 each track...() method supports an optional timestamp as its final argument; this allows you to manually override the timestamp attached to this event. The timestamp should be in milliseconds since the Unix epoch.

If you do not pass this timestamp in as an argument, then the JavaScript Tracker will use the current time to be the timestamp for the event.

Here is an example tracking a structured event and supplying the optional timestamp argument.

ghct_name_here("trackSelfDescribingEvent", {"schema": "iglu:com.acme/event/jsonschema/1-0-0", "data": {"type": "user_action"}}, [], 1368725287000)

Timestamp is counted in milliseconds since the Unix epoch - the same format as generated by new Date().getTime().

Also you can attach a true timestamp to the event, replacing the device timestamp. For example:

ghct_name_here("trackSelfDescribingEvent", {"schema": "iglu:com.acme/event/jsonschema/1-0-0", "data": {"type": "user_action"}}, [], {type: 'ttm', value: 1368725287000})

Above will attach ttm ([ true_tstamp][model-datetime]) parameter instead of default dtm. You can also use, plain number or {type: 'dtm', value: stamp} to send device_sent_timestamp.

2.9 Preserving pageViewId

As explained in webPage section, JS tracker regenerates webPage context each time trackPageView was called. However, before 2.7.0 this was not always the case - webPage context was regenerating only when whole HTML page loaded, initialising the tracker. It means pageViewId would remain same on many single-page applications. This behaviour was considered a bug, but if for some reasons you need restore old behaviour you can use preservePageViewId method:

ghct_name_here("preservePageViewId")
Copy this link : http://developer.goodharvest.co/ghct.js
X

Contact Form