Web setup

This is for:

Developer

This article explains how to set up Coveo Experimentation Hub (CEH) on your site.

Setup steps

Perform the following steps:

Add scripts

In this first step, you must add the UV API and smartserve.js scripts to each of your website pages.

UV API

CEH uses data generated by the events emitted on your website. The UV API exposes a common interface for emitting events.

It should be included as an inline script on each page at the top of the head tag, or as early in the head as possible. By embedding the API in the head synchronously, any script in the page is able to emit or handle events without polling or waiting for asynchronous scripts to load.

See Coveo Experimentation Hub scripts for more information.

<script>
!function(){function n(){function n(n){p.level=n}function e(n,e){p.info(n,"event emitted"),e=c(e||{}),e.meta=e.meta||{},e.meta.type=n,u.push(e),r(),v.listeners=f(v.listeners,function(n){return!n.disposed})}function o(n,e,o){function r(){return p.info("Replaying events"),t(function(){s(v.events,function(t){c.disposed||l(n,t.meta.type)&&e.call(o,t)})}),f}function i(){return p.info("Disposing event handler"),c.disposed=!0,f}p.info("Attaching event handler for",n);var c={type:n,callback:e,disposed:!1,context:o||window};v.listeners.push(c);var f={replay:r,dispose:i};return f}function t(n){p.info("Calling event handlers"),a++;try{n()}catch(n){p.error("UV API Error",n.stack)}a--,r()}function r(){if(0===u.length&&p.info("No more events to process"),u.length>0&&a>0&&p.info("Event will be processed later"),u.length>0&&0===a){p.info("Processing event");var n=u.shift();v.events.push(n),t(function(){s(v.listeners,function(e){if(!e.disposed&&l(e.type,n.meta.type))try{e.callback.call(e.context,n)}catch(n){p.error("Error emitting UV event",n.stack)}})})}}function i(n,e,o){var t=v.on(n,function(){e.apply(o||window,arguments),t.dispose()});return t}function s(n,e){for(var o=n.length,t=0;t<o;t++)e(n[t],t)}function c(n){var e={};for(var o in n)n.hasOwnProperty(o)&&(e[o]=n[o]);return e}function l(n,e){return"string"==typeof n?n===e:n.test(e)}function f(n,e){for(var o=n.length,t=[],r=0;r<o;r++)e(n[r])&&t.push(n[r]);return t}var u=[],a=0,p={info:function(){p.level>n.INFO||console&&console.info&&console.info.apply(console,arguments)},error:function(){p.level>n.ERROR||console&&console.error&&console.error.apply(console,arguments)}};n.ALL=0,n.INFO=1,n.ERROR=2,n.OFF=3,n(n.ERROR);var v={on:o,emit:e,once:i,events:[],listeners:[],logLevel:n};return v}"object"==typeof module&&module.exports?module.exports=n:window&&void 0===window.uv&&(window.uv=n())}();
</script>

smartserve.js

The Smartserve script is a JavaScript bundle hosted on a CDN, which contains all the code that CEH uses to collect data, compute segments, and serve experiences.

<script src="https://static.goqubit.com/smartserve-<YOUR_PROPERTY_ID>.js" async></script>

To ensure the best possible data accuracy and experience delivery, it is important to place this script tag as early as possible on the page.

It is also recommended to put this in the page header with an async script tag, so that the script is non-blocking.

Be aware that deploying the script through a tag manager or at the end of the file can cause low-data capturing rates.

See Coveo Experimentation Hub scripts for more information about implementing Smartserve and other CEH scripts.

Emit events

Note

For clients mapping existing data layer objects to QProtocol or for clients using page scraping, events are emitted directly in the page source and mapped to QProtocol events using uv-maps, a module bundled into smartserve.js. In this implementation scenario, this step can be ignored.

Emit events using UV API:

uv.emit(type, [data])

To ensure our scripts can consume information about the page and the visitor in a reliable way, your events must conform to our event types schemas and payloads.

Events are used in many ways by CEH. For example, they can:

  • determine whether a visitor is in a segment or not

  • decide whether to serve a specific experience or not

  • inform the content of an experience

  • help understand the impact of an experience on goals like increasing a visitors' likelihood to purchase

You can listen for events in the browser and react to them in real time, or wait for them to get sent to our servers where they will be processed and stored in order to power our products and services.

Example

<!-- Emit events from anywhere in your page -->
<script>
    uv.emit('ecView', {
      type: 'product'
    })

    uv.emit('ecProduct', {
      eventType: 'detail',
      product: {
        productId: '1209012233',
        name: 'Stainless Steel and Leather Watch'
      }
    })
</script>
Note

Before sending an event to the backend, smartserve.js retrieves context data stored in cookies and meta data such as the URL of the page.

This data will be available to query.

Warning

Any CEH events emitted before the first ecView event are considered invalid. Web and mobile applications emit CEH view events whenever a view is rendered.

Which events to emit

Which events you emit depends on your vertical - CEH has specific events for ecommerce, eGaming, Travel, publishing, logistics, and finance verticals.

We provide setup guides as an introduction to setting up CEH on your site. The events listed in these guides represent the basic set of events that are required to get started with basic data collection, segmentation, and personalization:

Validate your setup

It is important to understand the criticality of emitting events that conform to our QProtocol schema and payloads. Validating your setup is therefore a crucial stage in setting up CEH on your site and should not be overlooked. We highly recommend paying particular attention to our setup guides and the field-level requirements for each event.

CEH has tools to help you validate your setup. Refer to the following articles:

Example setup

Here is how all the scripts and event emitting look like all together:

<html>
<head>
  <title>Your Website</title>


  <!-- Embed the uv api so that we can send events easily -->

  <script>
  !function(){function n(){function n(n){p.level=n}function e(n,e){p.info(n,"event emitted"),e=c(e||{}),e.meta=e.meta||{},e.meta.type=n,u.push(e),r(),v.listeners=f(v.listeners,function(n){return!n.disposed})}function o(n,e,o){function r(){return p.info("Replaying events"),t(function(){s(v.events,function(t){c.disposed||l(n,t.meta.type)&&e.call(o,t)})}),f}function i(){return p.info("Disposing event handler"),c.disposed=!0,f}p.info("Attaching event handler for",n);var c={type:n,callback:e,disposed:!1,context:o||window};v.listeners.push(c);var f={replay:r,dispose:i};return f}function t(n){p.info("Calling event handlers"),a++;try{n()}catch(n){p.error("UV API Error",n.stack)}a--,r()}function r(){if(0===u.length&&p.info("No more events to process"),u.length>0&&a>0&&p.info("Event will be processed later"),u.length>0&&0===a){p.info("Processing event");var n=u.shift();v.events.push(n),t(function(){s(v.listeners,function(e){if(!e.disposed&&l(e.type,n.meta.type))try{e.callback.call(e.context,n)}catch(n){p.error("Error emitting UV event",n.stack)}})})}}function i(n,e,o){var t=v.on(n,function(){e.apply(o||window,arguments),t.dispose()});return t}function s(n,e){for(var o=n.length,t=0;tn.INFO||console&&console.info&&console.info.apply(console,arguments)},error:function(){p.level>n.ERROR||console&&console.error&&console.error.apply(console,arguments)}};n.ALL=0,n.INFO=1,n.ERROR=2,n.OFF=3,n(n.ERROR);var v={on:o,emit:e,once:i,events:[],listeners:[],logLevel:n};return v}"object"==typeof module&&module.exports?module.exports=n:window&&(window.uv=n())}();
  </script>

  <!-- Embed the asynchronous smartserve.js script that will load CEH -->
  <script src='https://static.goqubit.com/smartserve-{YOUR_PROPERTY_ID}.js' async />
</head>
<body>
  <div>Hello</div>

  <!-- Emit events from anywhere in your page -->
  <script>
    uv.emit('ecView', {
      type: 'product'
    })

    uv.emit('ecProduct', {
      eventType: 'detail',
      product: {
        productId: '1209012233',
        name: 'Stainless Steel and Leather Watch'
      }
    })
  </script>
</body>
</html>