Skip to main content

Shopify - Pixel - Metric Capture

O
Written by Optimize Team
Updated yesterday

Note: This document is being actively edited with a v2 of the pixel that allows for users on multiple subdomains.

Webtrends Optimize has the ability to collect numerous events from Shopify:

Events we can collect

If you would prefer that we change what we capture, there are options to customise this in the code provided below.

Unless stated otherwise, we do not rename events to avoid confusion between ourselves and Shopify.

Preparation

If you are using cookies instead of localstorage to preserve test decisions, you will need to add this code to your preinit script:

WT.addEventHandler("pageview", function(e){
var ta = e.target.params.testAlias;
var curCookie = WT.helpers.cookie.get("_wt.entrieslist") || ""; curCookie = curCookie.split(",");

if(curCookie.includes(ta)) return;

curCookie.push(ta);
curCookie = curCookie.join(",");

WT.helpers.cookie.set("_wt.entrieslist", curCookie, 14);
});

Shopify pixels don't let you read all cookies through document.cookie, and so we use this _wt.entrieslist cookie to keep track of what to fetch.

Required values

You will need your Account ID.

You can find this in your Account Settings area

Or, if you're on your website, you can paste this code into the console:

let { s_keyToken: token, s_domainKey: domain } = WT.optimizeModule.prototype.wtConfigObj;
console.log({token, domain});

Installation

At the top of the code provided below, please update the domain in the relevant areas. Other than this, you can copy/paste the code as detailed below.

Pixel code

analytics.subscribe("all_standard_events", async event => {
// ---- Configure this area :: START ----
let domain = '110205';
let eventsToIgnore = "page_viewed"; // comma seperated
// ---- Configure this area :: END ----
function projectToControl(cookieVal) {
var v = decodeURIComponent(cookieVal).split('||');
var ids = v[1].split('-').reverse();
var testid = ids.pop();
var runid = ids.pop();
var trackid = ids.reverse().join('-');
var value = {
"runid": runid,
"testGroup": "default",
"testid": testid,
"throttleResult": v[3],
"trackid": trackid,
"typeid": parseInt(v[0])
};
if (v[2] !== 'undefined') value.pageTrack = v[2] === 'true';
if (v[4] && v[4] !== 'undefined') value.targetData = JSON.parse(v[4]);
if (v[5] !== 'undefined') value.throttleRunVersion = v[5];
if (v[6] !== 'undefined') value.throttleTestVersion = v[5];
return value;
}
function WTO_CTrack2 (params) {
//global
var CSURL = '';
var accountId = domain;
var eventName = params.conversionPoint;
var data = params.data;
var cookies = params.cookies;
//sanitize custom data
if(Object.keys(data).length){
for(const key in data){
data[key] = String(data[key]);
}
}
//date time
var dateString = new Date().toISOString().replace('T', ' ').substring(0, 19);
var offsetValue = function() {
var rightNow = new Date;
var offset = -rightNow.getTimezoneOffset() / 60;
return offset * 1E3 * 60 * 60
};
//projects
var user = JSON.parse(cookies['_wt.user']);
var sessionId = user.userSession.split('-')[1];
var expIds = [];
var testIds = [];
for (var cookie in cookies) {
var val = cookies[cookie];
var isControlCookie = cookie.indexOf('_wt.control') > -1;
var notThrottledOut = val.throttleResult != 'OUT';
var hasTracked = val.hasOwnProperty('pageTrack')
if (isControlCookie && notThrottledOut && hasTracked) {
//test id
var testId = parseInt(`${val.testid}${val.runid}`);
//exp id
var expId = val.trackid;
if (expId < 0) { expId = 0; }
//target
if (val.hasOwnProperty('targetData')) {
expId = 0;
for (const id in val.targetData) {
var targetExpId = val.targetData[id];
expId = parseInt(targetExpId);
}
}
//baseline
else if (expId && expId == 'NOTRACKID') {
expId = 0;
}
//ab, mvt
else {
expId = parseInt(expId);
}
testIds.push(testId);
expIds.push(expId);
}
}
//payload
var trackPayload = {
"domainId": parseInt(accountId),
"testId": testIds,
"visitorId": user.uid,
"experimentId": expIds,
"sessionId": sessionId,
"eventName": eventName,
"user agent": navigator.userAgent,
"dateTime": dateString,
"timeZone": offsetValue(),
"customData": data
};
//send request
if (testIds.length > 0 && expIds.length > 0) {
var trackPayloadJson = JSON.stringify(trackPayload);
if (navigator.sendBeacon && window.Blob) {
var blob = new Blob([trackPayloadJson], { type: 'text/plain' });
navigator.sendBeacon(CSURL, blob);
} else {
var xhttp = new XMLHttpRequest();
xhttp.open("POST", CSURL, true);
xhttp.setRequestHeader("Content-type", "text/plain");
xhttp.send(trackPayloadJson);
}
}
}
try {
let name = event.name;
eventsToIgnore = eventsToIgnore.split(',');
if(eventsToIgnore.includes(event.name)) return;
let projectCookies = {};
let taList = [];
let userCookieName = '_wt.userdc-'+domain;
let usercookie = await browser.cookie.get(userCookieName);
var len = await browser.localStorage.length();
for(let i=0; i<len; i++){
let o = await browser.localStorage.key(i);
if (o.match(/_wt.userdc/i)) {
let userVal = await browser.localStorage.getItem(o);
usercookie = userVal;
}
else if(o.match(/_wt.dec/i)){
let val = await browser.localStorage.getItem(o);
let name = o.replace('_wt.dec', '_wt.control');
projectCookies[name] = JSON.parse(val);
taList.push( o.replace(`_wt.dec-${domain}-`, '') );
}
if(!o) break;
}
let wto_entrylistcookie = await browser.cookie.get('_wt.entrieslist');
if(wto_entrylistcookie && wto_entrylistcookie.length){
wto_entrylistcookie = wto_entrylistcookie.split(',');
for(let ta of wto_entrylistcookie){
if(!ta) continue;
let cookieoptions = [
`_wt.control-${domain}-${ta}`,
`_wt.project-${domain}-${ta}`
];
for(let cookiename of cookieoptions){
let cookieval = await browser.cookie.get(cookiename);
if(cookieval && cookieval.length){
taList.push( ta );
if(cookiename.match(/_wt.project/i)){
cookieval = projectToControl(cookieval);
}
projectCookies[cookiename.replace(/_wt.project/i, '_wt.control')] = cookieval;
}
}
}
}
if(!taList.length){
return; // no assignments, nothing to convert on.
}
let standardCookies = {};
if(usercookie) {
standardCookies['_wt.user'] = usercookie;
}
if(!usercookie){
return;
}
let data = {};
if(name == "checkout_completed"){
name = "purchase";
data.revenue = event.data?.checkout?.totalPrice?.amount || undefined;
data.units = event.data?.checkout?.lineItems?.length || 1;
}
let url = encodeURIComponent(event.context.window.location.href);
let reqbody = {
conversionPoint: name,
testAlias: taList.join(','),
cookies: {
...standardCookies,
...projectCookies
},
URL: url,
referrer: url,
data
};
WTO_CTrack2(reqbody);
}
catch(err) {}
});

How to install

Head over to Settings > customer events in your admin area

That should get you to this screen:

Click "Add custom pixel" and give it a relevant name like Webtrends Optimize

Next, apply the configuration to the pixel as you feel appopriate, e.g.:

Note that Webtrends Optimize does not resell your data, nor pay for it, and so it should be a safe option to select.

Finally, find the code section just below it, which will look like:

Paste in the code above, having updated your domain and keytoken. It should look like this:

Once you're happy, click Save in the bar at the top:

That's it. All being well, you should start tracking metrics from this point onwards.

How long does it take to get working?

We have seen it take upto 1 minute for our changes to take effect, but often it's under 5 seconds.

If you don't see it take effect immediately. we recommend hard-refreshes (Ctrl+Shift+R / Cmd+Shift+R) for a minute or so, and it should come through.

Final setup in Webtrends Optimize

We recommend adding the defaults to your Automatic tracking lists in Webtrends Optimize:

If you do so:

  • All of these metrics will show up when building tests to remind you we're capturing that information.

  • All Custom Data fields will be automatically attached to your tests, so you don't need to add them manually.

Did this answer your question?