Go to Qubit

Universal Variable documentation

Implementing UV

Implementing UV is divided up into two steps: adding the Opentag container, and implementing the Universal Variable data layer code.

Opentag container

This is the easy part. The Opentag container is one line of HTML that you can find in the Opentag interface. It might look something like this:

  <script src='//d3c3cq33003psk.cloudfront.net/opentag-xxxx-xxxx.js' async defer></script>
hy

You need to copy and paste the container code into the <head> block of every page on your website. If you haven’t got access to the Opentag dashboard, ask your client manager for the code.

Want to see a document instead? Read our fact sheet

Will it slow down my site?

Opentag containers and all tracking technologies within them load asynchronously by default. This means that no “blocking” will occur, resulting in an increased page-load time.

We don’t like putting third party tags in the head of the page.

The reason we ask for Opentag to be placed in the head of the page is because it allows the tags to load as soon as possible without compromising page load speed. As the Opentag container and all tracking tags within it load asynchronously by default, this will not result in any “blocking” or increases in page load time.

This is particularly important for A/B testing technologies (including Qubit’s personalization platform) to ensure no “flicker” occurs.

Do you have some kind of SLA?

Yes – 99.9% uptime. View this article for more details.

Why does it have to be on every page?

We ask for the Opentag container to be added on to every page of the site so tags can be added on any page required. On a lot of pages, the container might not actually do anything, but having it there provides the flexibility for rapid tag deployment.

Universal Variable code

This is the step that usually takes 1-2 development days work. What is required here is for you to implement the standard UV structure, (detailed in the code page), and populate the parameters with the appropriate values on every page of your website.

Heads up! You can’t just copy and paste UV code, you need to do some server-side programming to populate the fields.

The full Universal Variable code should be declared before the Opentag container.

For example, below is some PHP code setting some of the parameters within the transaction object.

<?php
  $transaction = array();
  $transaction['order_id'] = $order->getIncrementId();
  $transaction['currency'] = $this->_getCurrency();
  $transaction['subtotal'] = (float) $order->getSubtotal();
  $transaction['tax']      = (float) $order->getTaxAmount();
  $universal_variable->transaction = $transaction;
?>

In the front-end template files, this data should then be outputted in the immediately before the Opentag container.

<head>
  <title>Qubit Tools - Home</title>
  <script>
    window.universal_variable = <?php echo json_encode($universal_variable); ?>
  </script>
  <script src='//d3c3cq33003psk.cloudfront.net/opentag-xxxx-xxxx.js' async defer></script>
</head>

Libraries

We have helper libraries available for the following languages:

Get the codes

All make sense? Now it’s time to grab the codes!

Visit our code page

Validate your setup

We’ve got a great validator tool that you’ll hopefully find really useful. What it does is take a look at any given page and analyses the UV code, determining what’s right and what’s wrong about your setup.

This is great because it gives you feedback while you’re implementing the UV, meaning you can get things right first time.

Tip: Aim to get rid of all the red crosses. The !’s are the recommendations.

validator_preview

Go to the validator

On Magento?

At Qubit we’ve developed a Magento extension to provide the closest thing to an out-of-the-box solution for Universal Variable on the Magento CMS.

What does this mean?

That 95% of the work is already done for you. The majority of data required in the Universal Variable is being fetched by the extension and populated into the JavaScript object automatically.

Hang on, only 95%?

While the Magento extension takes away the majority of the work for you, there might be some additional data that your marketing team would like to be added into the data layer. This will likely take a small amount of development work for you to implement.

Does it work on Enterprise?

Yes. The extension works on both the community and enterprise editions.

How do we install it?

You can install the extension through Magento Connect in your admin panel, or through downloading it directly from Github.

On Hybris?

At Qubit we’ve developed a Hybris connector to provide the closest thing to an out-of-the-box solution for Universal Variable on the Hybris platform.

What does this mean?

That 95% of the work is already done for you. The majority of data required in the Universal Variable is being fetched by the extension and populated into the JavaScript object automatically.

Hang on, only 95%?

While the Hybris connector takes away the majority of the work for you, there might be some additional data that your marketing team would like to be added into the data layer. This will likely take a small amount of development work for you to implement.

How do we install it?

All the documentation is available on the Hybris Extend Market. In essence, it requires including our codebase into your project, adding a couple of calls into the layouts and setting a few configuration parameters. Once this has been done, and the platform rebuilt and deployed, then a new Qubit configuration section will appear in the backend to set your Qubit ID in (provided by your Strategist).

On Demandware?

At Qubit we’ve developed a Demandware cartridge to provide the closest thing to an out-of-the-box solution for Universal Variable on the Demandware platform.

What does this mean?

That 95% of the work is already done for you. The majority of data required in the Universal Variable is being fetched by the extension and populated into the JavaScript object automatically.

Hang on, only 95%?

While the Demandware cartridge takes away the majority of the work for you, there might be some additional data that your marketing team would like to be added into the data layer. This will likely take a small amount of development work for you to implement.

How do we install it?

All the documentation is available on the Demandware Link Marketplace. In essence, it requires including our codebase into your project, adding some custom code to the storefront cartridge and setting a few configuration parameters. Once this has been done, and the platform rebuilt and deployed, then a new Qubit configuration section will appear in the backend to set your Qubit ID in (provided by your Strategist).

Event tracking

Universal Variable has event tracking built into its core, providing the ability to capture in-page events in a central location in your data model.

Use events to track interesting visitor behaviours such as key page interactions and secondary conversion events – anything you need flagged in analytics, or reacted to in the browser. For example:

  • A visitor has added a product to basket
  • Visitor has started the registration process and chosen the product they wish to trial.

It’s best practice when tagging up UV events to ask across the business – including data analysts and the marketing team – for key onsite actions they need visibility on or want to react to.

Firing events

This example code below is often attached to a jQuery event listener on the page (such as a button click), or triggered by other Javascript functionality the visitor has interacted with.

In this example, we wish to log that a product has been added to the basket, while categorising this action into a wider bucket of conversion goals that will make sense to our analyst down the road.

// Check the UV events array exists
window.universal_variable.events = window.universal_variable.events || [];

// Push an event into the array
window.universal_variable.events.push({
  "category": "conversion_funnel_goals",
  "action": "product_added_to_basket"
});

Read the full events specification here.

Pro tip: UV events allow you to abstract all tagging logic from your application, as it’s the only tagging-related code you’ll have to add. All other technologies can “listen” for UV events.

Listening and reacting to events

Within Opentag, it is possible to “listen” for these events, and respond accordingly. Example use-cases include:

  • Firing a tag when someone completes a signup form
  • Showing a thank you message when someone adds something to the basket

To execute some code when a particular event is fired, attach it to our UV Listener. Part of Qubit Opentag, this listens to changes to the Universal Variable object and allows you to fire code when a change is detected. In this example, we’ll listen to the events object.

To do this, you push an array containing a callback function into window.uv_listener. The callback should take an event object – which will be the Universal Variable event object that has just been fired.

// Check the UV Listener array exists
window.uv_listener = window.uv_listener || [];

// Create event listener 
window.uv_listener.push(['on', 'event', function(event){

  // See if fired event matches our criteria
  if (event.action === "whitepaper_downloaded"){

    // display message thanking the visitor
    displayLightbox();
  }
}]);

Triggering tags in Opentag when an event fires

For details on firing tags based on events in Opentag using the Opentag user interface, see this guide.

Reacting for changes to Universal Variable in the pageview

For details on listening for changes in any UV object- not just events – see the next section.

Integrating with Google Analytics

UV events can be mirrored with Google Analytics, but you might want to include a few GA specific properties.

View the full specification for full details.

Listening to changes

Beyond listening to events (see above), you can also listen to the Universal Variable during the pageview and trigger code when a particular object is changed.

For example, you may wish to run some code to display a layer to the visitor when an item is added to their bag. You can attach a listener to the length of the the basket.line_items property to fire a callback when the basket is updated.

// Firstly, check the UV Listener array exists
window.uv_listener = window.uv_listener || [];


// Fire a callback function on any change to UV:
window.uv_listener.push(["on", "change", callback]);

// Fire a callback function on any change to specific part of UV:
window.uv_listener.push(["on", "change:keyString", callback])

  // where "keyString" is a property path within the UV. For example:
  // "change:transaction" will fire if the transaction object is changed
  // "change:basket.line_items.length" will fire if products are added to or
  // removed from the basket

// Event listening:
window.uv_listener.push(["on", "event", callback])

// Note that the callback is expected to take an argument (the event object)
// and also do the processing to determine if the event is relevant.

The UV listener, along with other useful tools, will be available if you have a recent version of Opentag loaded onto your page.

Custom parameters

The use of custom parameters in UV is encouraged. Our core specification aims to cover the majority of use-cases, but there are plenty of other scenarios where custom parameters can be useful.

Examples of custom UVs:

  • The rating of a product
  • The subscription level of a customer
  • The pre-defined segment the customer sits in
  • Age of the customer

What this looks like in the code:

"user": {
  "name": "John Doe",
  "username": "jdoe",
  "user_id": "12134124",
  "email": "jdoe@example.com",
  "language": "en-gb",
  "returning": true,
  "facebook_id": 12345678901232345,
  "twitter_id": "johnthedoe",
  "subscription_level": "level 1" // custom
}

Note: As the subscription level sits within UV, it is possible to target & segment based on it, as well as passing the value back to tags served through Opentag. Implementing a custom key for use with the Qubit platform? Discuss with your Conversion Strategist the best method to structure your data.

Ajax-based pages

Universal Variable handles ajax pages (for example one page apps) well. Fundamentally UV is just a structure, how it is used on ajax pages does not differ too much from “regular” pages.

There are two things to bear in mind:

1. UV should reflect the state of the page

At any given point in time, the Universal Variable should provide an accurate data layer representation of the page.

Example: product size:

If a user changes the selected size on a product page, the product.size variable should change immediately.

Example: dynamic checkout

A more complex example, where the customer can go from the basket right through to the confirmation page without a page refresh.

As the user goes through the checkout process, the page.type and page.breadcrumb should be changed dynamically to reflect the current stage of the checkout. Also as the customer selects shipping information, the basket.shippingcost and basket.shippingmethod should be updated.

Most importantly, when the customer reaches the confirmation page, the basket variable should be deleted and the transaction variable should be used.

Tip: To determine the structure of the UV, it helps if you imagine your checkout steps as entirely separate pages.

The only difference is that the UV is being changed dynamically in the page, rather than being set explicitly in the by the CMS.

2. Events should be passed to the events array

Events are different, allowing the tracking of in-page events. Events do not have “state”, but often may fire as well when the UV state is changed. For more information on event tracking, see the event tracking section.

Acting upon changes

When these changes in “state” or events happen, they can be detected and acted upon. Usually this will be done within the Opentag or Qubit dashboard interfaces. See the listening to changes section for more detail.

Common pitfalls

Not declaring UV before Opentag

UV needs to be declared before the Opentag container, so the parameters are available for Qubit’s personalization technology and the tags served through Opentag. Ideally both should be declared fully in the <head>.

There is one exception to this rule:

  • On category listing pages, data is often fetched client side & asynchronously from a third party. In this case the asynchronous data should be populated later on the page, with the rest of the data declared in the as normal.

Trailing commas

Trailing commas are where a comma is declared after the last item in an object or array. This is invalid JSON, and will cause JavaScript errors in Internet Explorer versions 7 and lower. For example:

"user": {
  "user_id": "12134124",
  "name": "John Doe",  // error
}


"line_items": [{
  "product": {
    "id": "12321",
    "unit_sale_price": 50
  },
  "quantity": 1,
  "subtotal": 50
},] // error

For more information see trailingcomma.com.

Declaring UV on $(document).ready()

While it is ok to populate UV client-side rather than server-side (as long as it is all declared before the Opentag container), UV should not be populated asynchronously after the document has loaded.

The reason for this is that Opentag will load before the UV is declared, and the required parameters will not be available at runtime.

Loading the Opentag container via ajax

Another related issue is loading the Opentag container via ajax. This can result in a delay before the Opentag container loads, and cause A/B testing tools (including Qubit’s personalization platform) to load too late on the page, resulting in a “flicker” effect.

Variable types

When implementing the parameters in UV, ensure that the variables are all the correct format. For example, the product.unitsaleprice is a Number format, not a string:

// Incorrect
"product": {
  "unit_sale_price": "15"
}

// Correct
"product": {
  "unit_sale_price": 15
}

All formats are detailed in the specification. Any variable type errors will be picked up by our validator tool.

Setting blank variables

If variables are not available, do not populate blank or null variables. Instead, it is better not to declare them:

// Incorrect
"user": {
  "language": "en-gb",
  "facebook_id": null
}

// Correct
"user": {
  "language": "en-gb"
}

Not updating UV on ajax event

The aim of the UV is to reflect all the dynamic data that matters about the current state of a webpage at any point in time. See the ajax-based pages section for more details.

Already implemented another data layer?

If you’ve already implemented another data layer on your website, there’s a very good chance that we’ve already got a custom built adapter for it.

The data contained within the Universal Variable is similar to that contained within other formats defined by organizations such as Google and BrightTag. As the data is essentially the same, we can instantiate the Universal Variable object using a mapping module on our end. Little or no development should be required on your side, at least in the initial stages.

We’d recommend getting in touch with us to talk through this in more detail.

A word on privacy

This standard includes methods to represent personal data, such as users’ names and addresses. Before you implement universal variable, decide which personal information you wish to include. Then, ensure you only include personal information where necessary, for example:

  • A User object (including the user’s name) could be populated in pages served to a signed-in user
  • An Address object (e.g. the shipping address) on a thank-you page

Why include personal data in universal variable?

The intention of this standard is to reproduce information that may already be displayed on-screen in a more machine-readable format for a better user experience, not to disclose personal information to anyone who shouldn’t see it. Remember that any data in universal variable will only be accessible by scripts loaded on that particular page, and the use of personal data falls under your applicable data protection laws as normal.

Was this helpful?