This document describes commonly used methods which can be found in your CAPI tag.
WT.addEventHandler and the internal Events mechanism
Optimize has an internal events system, through which you can subscribe to receive acknowledgement of, and details above, various things that take place.
Importantly, you should note that these events are not called retroactively. If you wish to subscribe to events, ensure that your code runs before the events take place. For integrations, this is the reason why we subscribe to these events in preinit.
Subscription to the events system is handled through code similar to:
WT.addEventHandler("event_name", function(data){
// parse data here
});
Available events are as follows:
Pageview
This is the most common event to hook into, as it’s the key moment at which one would run a 3rd party integration to send data to Analytics tools, Screen Recording tools, Heatmaps, etc., sending them details of which Experiment a user has fallen into.
WT.addEventHandler("pageview", function(data){
// parse data here
});
Example of data passed into the callback:
{
"name": "pageview",
"params": {
"eventID": 01234567890
}
"state": "success",
"target": {
"params": {
"beacon": false,
"controlCookieTimeout": 1210000000,
"cookieConversionCheck": true,
"cookieInspection": true,
"cookiePath": "/",
"cookiePrefix": "_wt",
"crossAPI": false,
"data": {
"description": "Description from Meta tag",
"documentTitle": "Document Title",
"robots": "index,follow",
"theme-color": "#ffffff",
"viewport": "width=device-width,initial-scale=1.0,maximum-scale=1.0, user-scalable=0",
"_wm_TimeOffset": 3600000
},
"guid": "0123456-ta_testAlias-0123456-0123456",
"lightWeightMode": false,
"r_experimentID": 0123456,
"r_paused": false,
"r_runID": 0123456,
"r_runState": 0123456,
"r_type": "AB",
"testAlias": "ta_testAlias",
"_wt_sessionID": "01234567890123456"
},
"z1382": {
"body": {
"cookies": { // a list of cookies passed along in the request
"name": "value"
},
"data": {
// as above, data object passed along in request
}
}
},
"z7715": {
"process": {
"body": {
"cookies": {
// as above, cookies passed along in request
},
"factors": [
{
"name": "element_id",
"operation": 3,
"value": "WTOTest01.setLevel('F1', 'F1L1')"
}
],
"postScript": "your postrender code",
"preScript": "your prerender code"
},
"opcode": "process",
"opstatus": "success"
}
}
}
}
Example usage:
Let’s say you wanted to send some data to Google Analytics whenever pageviews take place. This code could go into your Pre-Init script:
WT.addEventHandler("pageview", function (e) {
var p = e.target.params;
var projectAlias = p.testAlias;
var testID = p.runID;
var experimentID = p.experimentID;
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: "optimize_view",
project_alias: projectAlias,
test_id: testID,
experiment_id: experimentID
});
});
Hide/Show
This event subscription relates to [page hide](loading process page) – the mechanism through which we ensure tests do not flicker. There are two times at which this event is triggered – when the page should hide, and when it should be revealed. The callbacks differ based on the context in whcih the event is called.
To subscribe to the hide_show event:
WT.addEventHandler("hide_show", function(data){
// parse data here
});
Example of data passed into the callback:
{
"name": "hide_show"
"params": {
"display": true
}
"state": "success"
}
Example usage:
Let’s say you wanted to build your own page hiding mechanism. This code could go into your Pre-Init script:
WT.addEventHandler("hide_show", function(data){
var action = data.params.display ? "show": "hide";
var cssID = "wt_pageHide";
if(action == "hide"){
WT.helpers.css.add("body { opacity: 0.00001 !important; }", cssID);
} else { /* action == "show" */
WT.helpers.css.del(cssID);
}
});
Conversion
For conversions which do not take place through a “fire and forget” method (REST, Beacon, opt_data, CTrack etc.), you can subscribe to a event where the status of the conversion is confirmed by OTS. This is helpful as a generic hook for QA purposes, but also allows you to consider your own mechanism for delaying element redirection.
Note that as we push more of our functionality into these fire-and-forget, ping-based mechanisms, this event will occur less and less.
To subscribe to the conversion event:
WT.addEventHandler("conversion", function(data){
// parse data here
});
Example of the data returned in the callback:
{
"name": "conversion",
"params": {
"eventID": 1597567487466
},
"state": "success",
"target": zf9ac
}
WT.click
This is our original method for adhoc metric capture. For example, capturing a click metric as part of your experiment.
It is a per-experiment action - saying "for test X, track metric Y".
Tracking a simple metric
WT.click({
testAlias: "ta_something",
conversionPoint: "click_something"
});
Tracking a metric with Custom Data
WT.click({
testAlias: "ta_something",
conversionPoint: "click_something",
data: {
dataPointA: "valueA",
dataPointB: "valueB"
}
});
Note that any custom data you send along needs to be specified in the Custom Data panel of the Advanced Editor. Doing so is not a feature available to the Visual Editor / WYSIWYG
WT.trackEvent
This is a method built in 2023 and added to some customer tags. Where available, it uses the Beacon API and thus is much more useful for tracking events on actions where the page redirects away, e.g. clicks of a link.
It accepts identical inputs to WT.click, making it an easy replacement.
Tracking a simple metric
WT.trackEvent({
testAlias: "ta_something",
conversionPoint: "click_something"
});
Tracking a metric with Custom Data
WT.trackEvent({
testAlias: "ta_something",
conversionPoint: "click_something",
data: {
dataPointA: "valueA",
dataPointB: "valueB"
}
});
opt_data
This requires integration opt_data
Let’s say you want to track some information in Optimize, but you’re unable to get to/share details about the page it’s on.
window.opt_data
provides a simple interface for sending additional data into Optimize, and can take place as part of your tag implementation if needed.
Wherever convenient, you can run this code. The tag will pick it up, and store those details as part of your conversion package. It can be inside SCRIPT
tags, inside your tag manager, etc.
Think of it as our equivalent to GTM's dataLayer.push
method.
Sending an event only
window.opt_data = window.opt_data || [];
window.opt_data.push({ "event": "purchase" });
Sending an event with additional data
window.opt_data = window.opt_data || [];
window.opt_data.push({
"event": "purchase",
"data": {
"revenue": 123.45, // Replace this value with your dynamically-inserted revenue.
"upt": 3 // Replace this value with your dynamically-inserted units purchased value. // provide any other attributes you'd like to here.
}
});
Passing in data before the tag has run:
The above code will see that window.opt_data
is not on the page, and will create the variable. It will then use .push
to insert your event details into the Array. Optimize will then pick this data up and pass it in as a conversion. This will happen for all tests that user is cooked for.
Once Optimize executes, you’ll then see this data in window.opt_data.h
Passing in data after the tag has run:
The above code will hit a pre-defined function, which will automatically send conversion data into Optimize for each test the user has fallen into. Your data will then be stored in window.opt_data.h
Knowing if opt_data is present
While there should be no need for you to know this, you can look for window.opt_data.h
. If present, that means Optimize has run.
WT.helpers – Utility Methods
WT.helpers
is the object in which you’ll find a handful of utility methods. These are things you are likely to require in various places throughout your work in the UI.
CSS
This helper allows you to Set and Remove CSS stylesheets, written the page with an easy-to-follow patten in JavaScript.
WT.helpers.css.add
This is the method to write stylesheets to the page.
The first argument is required, and is either a String or Array of strings. These hold the CSS rules you wish to write to the page.
The second argument is an optional String, which attaches an id attribute to the <style>
tag which gets written to the page. This is particularly useful if at some point you intend to remove the stylesheet.
// One CSS rule:
WT.helpers.css.add("#myElm { attribute: value; }");
// One CSS rule, with ID
WT.helpers.css.add("#myElm { attribute: value; }", "myStyleSheet");
// Multiple CSS rules
WT.helpers.css.add([
"#myElm1 { attribute: value; }",
"#myElm2 { attribute: value; }",
"#myElm3 { attribute: value; }"
]);
// Multiple CSS rules, with ID
WT.helpers.css.add([
"#myElm1 { attribute: value; }",
"#myElm2 { attribute: value; }",
"#myElm3 { attribute: value; }"
], "myStyleSheet");
WT.helpers.css.del
A simple method to delete your stylesheet. In reality, this method actually removes any element by the provided id.
WT.helpers.css.del("myStyleSheet");
Cookies
WT.helpers.cookie.get
This returns the value of a cookie, or null if not found.
WT.helpers.cookie.get("cookiename");
// returns value of cookie, or null.
WT.helpers.cookie.set
This sets a first-party cookie to the page. It has various arguments:
Name, required, String – the cookie name
Value, required, String – the value you want to assign to the cookie
Expiry, optional, Integer – the time in days you want the cookie to expire in. If no value provided, it becomes a session cookie.
Path, optional, String – the path value you want to be written into the cookie. Defaults to /.
Domain, optional, String – the domain you want to be written into the cookie. Defaults to the top-level domain the page is on. Useful if you want to restrict the cookie to a subdomain.
WT.helpers.cookie.set(name, value, expiry, path, domain);
// e.g. Session cookie
WT.helpers.cookie.set("cookieName", "cookieValue");
// e.g. Cookie with 30 day expiry
WT.helpers.cookie.set("cookieName", "cookieValue", 30);
WT.helpers.cookies.del
Deletes a cookie by a given name.
WT.helpers.cookie.del("cookie_name");
WT.helpers.loadFileAsync
As the method suggests, this loads a file asynchronously. A script file. It accepts two arguments:
URL, required, string – the URL of the script file you want to write to the page
Callback, optional, function – a function that will execute onload of the script.
// e.g. Load a file:
WT.helpers.loadFileAsync("https://c.webtrends-optimize.com/myscript.js");
// e.g. Load a file with a callback WT.helpers.loadFileAsync("https://c.webtrends-optimize.com/myscript.js", function(){
console.log("it loaded!");
});
WT.helpers.device
This is a self-executing function, which holds the value of Device Type – ”desktop”
, ”tablet”
or ”mobile”
.
It can be accessed as WT.helpers.device. This is a basic check using some rudimentary conditions – nothing to the power behind our segmentation engine, but often helps to accomplish a straightforward goal.
WT.helpers.bdebug.x
Leaving stray console logs in your work is not advised for any of the work that we do. Clients will often pick up on it, perhaps leaking into monitoring tools, and can confuse the logging and reporting they have.
To help with this problem, we suggest all logging take place through a proxy-function. The principle is that the logs or alerts will only trigger if you have the cookie _wt.bdebug=true
. For normal users, who won’t, the logs won’t be relayed to window.console
or window.alert
.
Available methods include:
WT.helpers.bdebug.log
– a proxy for console.logWT.helpers.bdebug.info
– a proxy for console.infoWT.helpers.bdebug.warn
– a proxy for console.warmWT.helpers.bdebug.error
– a proxy for console.errorWT.helpers.bdebug.dir
– a proxy for console.dirWT.helpers.bdebug.alert
– a proxy for window.alert
WT.helpers.findVariationName
By default, Optimize does not relay “friendly names” to the front-end. The [Optimize Build Framework] is the only exception to this rule, where names are transmitted to the front-end based on however you choose to code them. We have generic names as standard, but you’re able to modify the code as you see fit.
WT.helpers.findVariationName is an easy and uniform way to get your test name and variation name, without having to worry about the intricacies of the type of project you’re running.
To call the method, you provide a testAlias to performa lookup on.
WT.helpers.findVariationName("ta_myTest");
It returns an Object containing your test name and variation name:
{
"testName": "Test 1 - Homepage USP ABn",
"variationName": "1 - Free Delivery"
}
This call is often used in conjunction with Pageview/addEventHandler event subscriptions, as described above.
WT.Sizzle
SizzleJS is the selector engine used by our Visual Editor (VE). It is availble under WT.Sizzle
.
When you’re in the VE and click on an element, a selector reference is generated specifically for that element. When rendering the projects on the page, these selectors are passed into WT.Sizzle
to fetch the matching elements.
Sizzle is the same selector engine used by jQuery, and greatly extends what's available via. querySelector.
Whilst the Visual Editor is the primary use-case for having the library, you are also free to utilise the library in your projects if you choose to. There are some useful examples below:
var $s = WT.Sizzle;
$s('body') // get the "body" element
$s('div.myclass') // get all "div"s that have the classname "myclass"
$s('span:contains(Total)') // get all "span"s that contain the text "Total"
$s('span[attribute="value"]') // get all "span"s with this attribute/value exact match
$s('span[attribute*="value"]') // get all "span"s with this attribute/value partial match (actual value must contain queried value)
$s('span:not(.myClass)') // get all "span"s that do not have myClass as a classname
– Lookup