NAV
JavaScript
  • Custom Data
  • Custom Data

    Context

    Custom data are one of the most powerful features of the Kameleoon platform. They allow any kind of data to be easily associated with each visitor and used for many different purposes. The two main uses are to build targeting segments for personalizations based on this data, or to provide advanced analytics reports featuring this information. Various external sources can be used to provide the data to Kameleoon, such as data layers, DMPs, CRMs, or custom web services. Examples of custom data can be diverse: age, sex but also previous purchases, current cart amount, favorite category... Usually custom data are very dependent on the specificities of your own business: if you're running an website similar to eBay for instance, you may want to indicate as a custom data whether a particular visitor is mostly a "buyer" or a "seller".

    The distinct features of Kameleoon make the use of custom data both much easier (simpler to setup, implement and maintain) and more flexible (allowing complex use cases and personalization scenarios) compared to similar concepts on other analytics platforms. For instance, Kameleoon custom data can be seen as a much more advanced version of Google Analytics' Custom Dimensions.

    This article is a general guide for developers to learn more about custom data and how to use them in the most effective way. If only one aspect of Kameleoon's custom data should be remembered, it's that even though they are intended to be used in the context of a visit on a web site, they are by default historized. This means that their lifespan is not limited to the JavaScript environment of the current page (as is the case with Tag Managers / Data Layers). This unlocks the possibility to implement really advanced personalizations, A/B experiments or business reports.

    Technical Overview

    Once a custom data is acquired, it is written in the LocalStorage of the current device. The internal Kameleoon engine takes care of saving and loading, as well as many complex issues such as concurrent access from several opened tabs on the same website. This allows this data to be retrieved later in all subsequent page views of the same visit, or in future visits. You can expect any custom data that you write at some point to be automatically available for use later, either via our Activation API or in segments, as soon as Kameleoon is loaded.

    Our implementation of local storage is cross-domain, which means that you do not need to be concerned about user journeys spanning several domains and/or protocols (HTTP and HTTPs). If you correctly followed our implementation guidelines, this is automatically handled by Kameleoon and there is no loss of data from one domain to another. However, if you wish that your custom data be replicated from one device to another, OR if you use a server to server acquisition method for the custom data (via our Data API), server synchronization calls must be used. See the dedicated section on this topic for details.

    Note that any custom value that you set (provide a value for) will be sent to our data collection servers as part of the usual Kameleoon tracking process. This happens in addition to their storage in the LocalStorage. The server calls are made asynchronously, without any associated performance hit. This serves three purposes. First, the data will be available for reporting purposes (filters, breakdowns, metrics) in the Kameleoon analytics. Second, this data will be taken as (often valuable) input for our machine learning algorithms. Third, these data are stored in our Data API backend servers, and they can then be retrieved by synchronization calls if needed.

    General characteristics

    When defining a custom data (via the Kameleoon back-office application), several characteristics of this custom data must be provided. These are documented here.

    Type

    Kameleoon.API.CurrentVisit.customData["visitedCategories"] == [{"value": "Computers", "count": 3}, {"value": "Phones", "count": 1}, {"value": "Games", "count": 7}]; // example of a Counted List custom data
    

    As in most programming languages, the type of a custom data should be specified. It can be a Boolean, Number or String of characters. More importantly, a custom data can be a list of values (example: a list of all the categories of products seen by this visitor) or even a counted list. A counted list is a list of different values, with a count of how many times each particular value was set. For instance, a custom data representing the list of categories seen by a visitor, along with how many times these categories were seen, should use a counted list.

    Scope

    The scope of a custom data is important, and can take three values: PAGE, VISIT or VISITOR.

    Options

    Only stored on LocalStorage

    If this option is checked, the custom data value is only stored on the user device (via the LocalStorage) and is never sent accross the network to our servers. This can be useful for privacy or legal reasons. Indeed, some customers must ensure that some sensitive data is not stored anywhere outside of their own IT systems, but would still like to target their visitors in a personalization according to this data. Of course, this means that all functionalities that require the data to be available on our servers are also disabled (details here). However, core custom data functionality, such as use for targeting, is still available.

    Input for Machine Learning

    If checked, this particular custom data will be used as an input for our machine learning algorithms. This option is only available if you subscribed to the A.I. Personalization module.

    Cross-device history reconciliation

    This enables cross-device history reconciliation, discussed in this article.

    Advanced Settings

    Implement a custom select box interface for the targeting condition associated with this custom data

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "https://third-party.dmp.com/get-segments?login=XXXX@XXXX.com&password=XXXX", false);
    
    var segments = [];
    xhr.onreadystatechange = function() {
    
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
            var data = JSON.parse(xhr.response);
            data.map(function (segment) {
              if (segment.segment_uuid && segment.name !== "undefined") {
                segments.push({"label": segment.name, "value": segment.segment_uuid});
              }
            });
        }
    }
    
    xhr.send();
    return segments;
    

    This feature allows you to present a select box when using this custom data in a targeting condition, rather than a plain text field. It's thus much easier for the end-user to select the value on which to target. Two very interesting points should be noted:

    In practice, this makes it very easy to build bridges / integrations with third party data providers such as DMPs or CRMs. For instance, if this custom data represents an external segment from a DMP, the user can select "Loyal customers" instead of "8ney4225y65a" which would be the actual value (usually internal ID) for this segment in the DMP. The list of defined segments on the DMP would always be up to date on Kameleoon's interface as well: this feature takes care of the synchronization.

    To implement this feature for a given custom data, you must provide some JavaScript code that will return synchronously a JS array containing objects representing the possible values along with their labels. This array should obey the following requirements:

    Look at the code sample to see an example of how this feature can be used in practice. Here we make a remote call to a third party server (usually a DMP or similar platform) that will provide us with the list of available segments defined on this platform. It's important to understand that this code is only used to build the selection interface for the Kameleoon end-user. Retrieving and setting the actual value for the custom data during the customer's visit on your website is a totally independent and separate process, described in the next section about Acquisition Methods.

    Acquisition Methods

    The way you supply the custom data value to Kameleoon must be specified. We support various integrations out of the box, mostly with data layers. You can also use our APIs (either the Activation API for client-side acquisition in JavaScript, or the Data API for server to server transfer) or provide ad-hoc custom JavaScript code (which is client-side based and is similar to using the Activation API).

    Google Tag Manager, Tealium, Commander's Act

    These methods directly take the value of the custom data from a given variable in the target solution data layer. Thus you don't need to do anything else apart from specifying the name of the variable in your usual data layer. Integration is done automatically as soon as the data layer is loaded on your page.

    Activation API

    Using our Activation API should be the standard way of setting custom data values on the browser (client-side environment). For instance, you can directly locate a particular DOM element on the page, and get its content as value for the custom data. In this way, you can obtain the current cart amount value if it is displayed on the web page, and fill the corresponding custom data accordingly.

    The Activation API is documented in detail here. Kameleoon.API.Data.setCustomData() is the main method that should be used.

    Custom Code

    if (! window.myObject) return null; // custom data will not be set, but code will re-run later
    
    if (window.myObject) return {"value": window.myObject.x, "overwrite": true}; // returning a value and setting the custom data
    
    if (window.someObject.value == 3) return {"value": null} // stopping the periodic execution of the code, without setting the custom data
    

    This option allows you to write ad hoc custom JavaScript code. The main rule to follow when setting a custom data is that your code should return an object with two keys, "value" with the value you want to provide for this custom data, and (optionally) "override" with a boolean value (false by default).

    If you don't yet have any value to provide for this custom data, but will obtain it later on this page, don't return any value (you can also return null or undefined). Your code will in that case be executed again (every 100 ms for the first 3 seconds after the first invocation, then every 3 seconds). By convention, returning {"value": null} will not set the custom data, but will stop the regular execution of your code.

    The first execution of your code will take place before the Kameleoon targeting system is triggered, thus giving you the chance to setup your custom data before targeting is executed.

    Data API / Server to Server integration

    Our Data API should be used if you want to setup a server to server integration. The basic principle is to implement a REST call to our servers, specifying the custom data name and value, as well as the visitorCode. The documentation for our Data API is not yet available but we expect it to be ready for Q2 2021.

    Other options for server to server integrations are also possible, such as uploading a file to a Kameleoon FTP server that will later be parsed by a custom script. The script will then inject the parsed content into our data servers.

    Using Custom Data

    Targeting condition for segments

    Kameleoon segment builder will automatically add targeting conditions for any custom data that you define. Everything is done automatically here, and if the value of the custom data corresponds to your condition, this particular visitor will be included in the segment.

    Via the Activation API

    You can obtain the current value of a custom data via Kameleoon.API.CurrentVisit.customData (PAGE or VISIT scopes) or Kameleoon.API.Visitor.customData (VISITOR scope).

    Analytical Purposes

    Any custom data (except those marked as local only) can be used as a filter or a breakdown option in our experiment or personalization result pages. Additionally, this information is also available in reports produced by our raw data export tool, and complex queries including those custom data can be performed on Elasticsearch clusters (if you opted for a dedicated Kameleoon Elasticsearch cluster).

    For a breakdown with a String type custom data, the results will be broken down with a maximum of 50 possible values for this custom data. The 50 most frequently used values for the custom data are used.

    For a breakdown with a Number type custom data, the results will also be broken down with a maximum of 50 possible values. In the case of numerical custom data, this does not always make sense. The possibility to define ranges and use them in breakdowns will be implemented in our platform in 2021.

    Server Synchronization Calls

    By default, during the initialization of the Kameleoon engine (which as a JavaScript application, happens on every page view), the necessary data are retrieved from the LocalStorage, decoded and made available for use. This process is entirely local to the current device, without any associated remote server calls. This is a very elegant solution that favors both performance and simplicity of code, as developers have a guarantee that custom data are available directly, without any need for checks and potential delays. Unfortunately, there are 3 situations where server synchronization calls (SSCs) are mandatory to obtain accurate information for setting up the custom data of a visitor. Without this synchronization with the data stored on our servers, custom data may be missing or their values outdated.

    Note that server synchronization calls are only available if you subscribed to our Personalization module. If you don't have this module available, the issues caused by the three previously described situations cannot be solved, and thus you should not rely too heavily on custom data. However, note that the variation allocations are linked to the visitorCode, which can be stored in a cookie. So operating coherent A/B tests is possible with only the A/B testing module, even for ITP 2.3 restrictions.