Conductrics - Intro to Page Editing for Simple A-B Testing

Problem

We have deployed the Conductrics optimization solution on our site and now we want to quickly get our first A-B test up and running.

Actions

In this 8-minute video, Matt Gershoff, CEO of Conductrics, will walk you through how to use the Conductrics point-and-click tools called ‘WAX” to visually make changes to your site and then launch your first A-B test.

References

Video: Intro to Page Editing for Simple A-B Testing
Conductrics documentation


Adobe DTM - Set and Record Visitor type

Problem

As an analyst you want to segment website visitors. For an eCommerce website, perhaps you want to segment your visitors into prospects, leads and customers. But many times, you just know the type, if a visitor purchased (and thus, becomes a “customer”).

Actions

We will set up a data element using custom JavaScript to identify the visitor type. The explanation will be split into a example with a full data layer and one without a data layer. The first approach was a little bit different to the result now. Peter O’Neill outlines this technique in a great L3 Analytics Blog post titled Understanding your Website Visitors: Prospects vs Customers.

Here is our visitor behavior hierarchy:

  • If the visitor has purchased, they are a customer
  • Otherwise, if the visitor is logged in, they are a lead
  • Otherwise, if we don’t know anything, they are a prospect.

This custom script uses localStorage and sessionStorage, not cookies. What’s the difference? Cookies are primarily for reading server-side, whereas local storage can only be read client-side. More information: What is the difference between localStorage, sessionStorage, session and cookies? And, if you are located in the EU, don’t forgett about the EU’s cookie law. LocalStorage and sessionStorage are treated as cookies.

Explanation (resolution)

Data layer available

Let’s begin by creating the data element. Name the data element in reference to the value which it will serve: visitorType. Copy and paste the following javascript into your data layer code:

if (typeof(Storage) !== "undefined") {
	if(sessionStorage.ssVisitorType === undefined) {
		if (digitalData.user.segment.loggedIn === "yes") {
			if (digitalData.user.segment.customer === "yes") {
				sessionStorage.setItem("ssVisitorType", "customer");
				localStorage.setItem("lsVisitorType", "customer");
			} else {
				sessionStorage.setItem("ssVisitorType", "lead");
				localStorage.setItem("lsVisitorType", "lead");
			}
		} else {
			if (localStorage.lsVisitorType !== undefined)) {
				sessionStorage.setItem("ssVisitorType", localStorage.getItem("lsVisitorType"));
			} else {
				sessionStorage.setItem("ssVisitorType", "prospect");
				localStorage.setItem("lsVisitorType", "prospect");
			}
		}
	} else {
		if (localStorage.lsVisitorType === undefined) {
			localStorage.setItem("lsVisitorType", sessionStorage.getItem("ssVisitorType"));
		}
	}
}
return sessionStorage.getItem("ssVisitorType");

In this code snippet, prospect is the default value (i.e. the absence of other information to place the user higher up on the hierarchy). Then, remember this value for a pageview and save the data element.

We use conditional statements to determine if web storage is supported by the browser and if the sessionStorage for the visitor type isn’t set. If so, we dig into the data layer and set the localStorage and sessionStorage to the equivalent visitor type. If there is no information available, we look up if the localStorage is set and if not the visitor type will be prospect.

We can also create two more data elements: visitorTypeLogin and visitorTypePurchase.

Here is the custom script for visitorTypeLogin, where the default value is lead:

if (localStorage.lsVisitorType === "prospect")) {
	if (digitalData.user.segment.customer === "yes") {
		sessionStorage.setItem("ssVisitorType", "customer");
		localStorage.setItem("lsVisitorType", "customer");
	} else {
		sessionStorage.setItem("ssVisitorType", "lead");
		localStorage.setItem("lsVisitorType", "lead");
	}
}
return sessionStorage.getItem("ssVisitorType");

Custom script for visitorTypePurchase, the default value is customer:

if (localStorage.lsVisitorType !== "customer")) {
	sessionStorage.setItem("ssVisitorType", "customer");
	localStorage.setItem("lsVisitorType", "customer");
}
return sessionStorage.getItem("ssVisitorType");

All custom scripts basically do the same thing, with slightly different business logic.

After this, we create three page load rules:

1) On every page, an eVar is set to %visitorType%. (It’s also possible to track this in the Adobe DTM properties, so then you wouldn’t even need an extra page load rule). 2) After a login, the eVar is set to %visitorTypeLogin%. 3) After a purchase, where the eVar is set to %visitorTypePurchase%.

The conditions should be evaluated after the data layer exists in the DOM. As an example, if the data layer is loaded after the opening <body> tag, the rule should be triggered at the bottom of page. If you’re using Adobe Analytics call, the tracking script should be after these page load rules to avoid two pageviews.

Data layer not available

If a data layer is not available, there is a slight change in the first two custom scripts and as you can imagine it will make tracking less accurate.

Custom script for visitorType, the default value is prospect:

if (typeof(Storage) !== "undefined") {
	if (sessionStorage.ssVisitorType === undefined) {
		if (localStorage.lsVisitorType !== undefined) {
			sessionStorage.setItem("ssVisitorType", localStorage.getItem("lsVisitorType"));
		} else {
			sessionStorage.setItem("ssVisitorType", "prospect");
			localStorage.setItem("lsVisitorType", "prospect");
		}
	} else {
		if (localStorage.lsVisitorType === undefined) {
			localStorage.setItem("lsVisitorType", sessionStorage.getItem("ssVisitorType"));
		}
	}
}
return sessionStorage.getItem("ssVisitorType");

Custom script for visitorTypeLogin, the default value is lead:

if (localStorage.lsVisitorType === "prospect")) {
	sessionStorage.setItem("ssVisitorType", "lead");
	localStorage.setItem("lsVisitorType", "lead");
}
return sessionStorage.getItem("ssVisitorType");

The page load rules in your tag manager would be the same.

View last Words

Please remember:

The first caveat is that this data will not be, and could never be, 100% accurate. For visitors who are not logged in, it is just not possible to know definitely whether they are an existing customer or a prospect. Your accuracy will improve over time as customers return and can be identified, even if they are not logged in. However, this does not work if they delete their cookie or use a different device. (see Peter O’Neill in “Understanding your Website Visitors”)

References

Understanding your Website Visitors: Prospects vs CustomersUnderstanding your Website Visitors: Prospects vs Customers
What is the difference between localStorage, sessionStorage, session and cookies?
EU’s cookie law


JSON Data Layer based on W3C norm

Problem

Quote from W3C Customer Experience Digital Data Layer:

“Collection and analysis of visitor behavioral and demographic data has become an integral part of web application design and website success, whether accessed through browsers on laptop, mobile, kiosk, tablet or another device. This data is central to site performance analysis, dynamically tailoring site content to visitor activity and interest and retargeting visitors based on their behaviors.

Increasingly, multiple vendors are involved in the data collection process for a given digital property, and each has a solution to be implemented on the page. As a result, page design has become more complex and development cycles have lengthened as different requirements for data surfacing and formatting are added to the implementation process. Further, changing or adding vendors sometimes requires that the development team change designs to accommodate vendor-specific requirements. Common data items must be continually surfaced in different ways, and each design requirement is a custom effort.”1 (p. 1)

Actions

To get rid of the standard way of collecting data from your website, you can use a structured data layer. For this JSON works well. JSON stands for JavaScript Object Notation and is a lightweight data-interchange format. JSON uses JavaScript syntax, but the JSON format is text only.

###Explanation resolution First of all think about what kind of data your want to collect. Try to segment them in a way where they belong to.

  • So the page name belongs to the page, same with referrer or server name.
  • Price and product name belongs to the product.
  • User State and ID belongs to the user.
  • And so on …

After this we have to divide these segments in a JSON object.

“The JSO is designed to be contained within a root object called digitalData – this is a matter of convenience and gives a common starting point. All other objects are sub-object from this root object. There is a pageInstanceID that is used to identify the page being measured within a unique environment – development, staging, or production, for example. Beyond that, the specification includes sub-objects such as page, product, cart, transaction, event, component, user, privacyAccessCategories, and version for collecting different types of data in the JSO. (Additional objects can be added to digitalData as part of the extension mechanism.) Within the sub-objects, the specification defines a number of standard names for properties, while custom properties can also be added through an attributes object.”1 (p. 9)

Lets have a look at an example:

digitalData="{
	"pageInstanceID":"Example Page:PROD",
	"page":{
		"pageInfo":{
			"pageName":"Example Page",
			"server":"www.example.com",
			"referrer":"www.digitalanalyticscookbook.org"
		},
		"attributes":{
			"country":"US",
			"language":"en-US",
		}
	},
	"product":[{
		"productInfo":{
			"productName":"Nikon SLR Camera",
			"sku":"sku12345",
			"manufacturer": "Nikon"
		},
		"category":{
			"primaryCategory": "Cameras"
		},
		"attributes":{
			"productType": "Special Offer"
		}
	}],
	"product":[{
		"productInfo":{
			"productName":"Canon SLR Camera",
			"sku":"sku67890",
			"manufacturer": "Canon"
		},
		"category":{
			"primaryCategory": "Cameras"
		},
		"attributes":{
			"productType": "Special Offer"
		}
	}],
}"

As you can see there is no limit having sub-objects in sub-objects. Only be aware of a straight JSON structure. If you have more than one sub-object with the same segment like a product, you have to use an array.

To get more ideas of what kind of sub-objects you can use, look at page 14 an following the the W3C Customer Experience Digital Data Layer.

To get the information out of the JSON, just use a JS object as for example digitalData.page.pageInfo.pageName is “Example Page” or digitalData.product[2].productInfo.productName is “Canon SLR Camera” in the data layer example above.

References

1 W3C Customer Experience Digital Data Layer