NAV
JavaScript
  • Back-end / Front-end Bridge
  • Back-end / Front-end Bridge

    Introduction

    Operating the Kameleoon platform both on the back-end (via server-side SDKs) and on the front-end (via JavaScript engine) is possible. This approach can actually be beneficial, as it allows you to choose different approaches for different tasks. For instance, your team could decide it is easier to implement and deploy variations on the back-end, but better to perform all tracking on the front-end, seeing as many third-party integrations with web analytics solutions (such as Google Analytics) only work on the front-end.

    This article describes how you can implement an optimal integration between Kameleoon Back-end and Kameleoon Front-end, and have both sides communicate with each other. It assumes Kameleoon is already properly installed in your back-end server as well as in your front-end HTML pages.

    Ensuring user identification consistency between the back-end and the front-end

    One of the challenges of using Kameleoon both on the back-end and the front-end is to make sure each visitor is properly identified as the same individual from both sides. In Kameleoon, this means that the visitorCode, which is a unique id for every user / visitor, has to be identical everywhere. This allows correct tracking of the visitor's actions, which in turn leads to correct data and statistics. Ie, a user registered with the visitorCode 10ctbql0zpf4rwjy for a variation of an experiment in the back-end also has to be associated with the same visitorCode when a conversion is triggered in the front-end.

    From back-end to front-end, communication is easy (for instance via embedded JavaScript code in the HTML pages). But sending information from front to back can be difficult for a third party platform with an integration that needs to be as painless as possible. The only practical way is to write a cookie, that our back-end SDKs will read and use. However, recent developments with Apple's Intelligent Tracking Prevention (ITP) technology, as well as similar approaches from other browser vendors, heavily restrict what JavaScript based solutions can do. With ITP 2.3, cookies deposited via JavaScript can only have a lifespan of seven days before expiring.

    So to ensure consistency between the back-end visitorCode and front-end visitorCode, we came up with the following approach.

    Client-side

    On the front-end side, a visitorCode is generated and assigned for every new visitor. A visitor is technically considered a new visitor if no previous visitorCode can be found by the engine for this user. This usually happens when the Kameleoon engine is run for the first time on the visitor's browser. The logic of the visitorCode assignment is the following:

    1. First we check if a kameleoonVisitorCode Local Storage key exists. If no, we check for the presence of the kameleoonVisitorCode cookie. If it is present, we will use this as the identifier for the visitor code. Else the identifier is generated randomly.

    2. If the Local Storage key does exist, we will use this as the identifier for the visitor code. This happens even if a kameleoonVisitorCode cookie with a different value is present, which means the identifier from the LS takes precedence.

    3. In any case, the defined visitorCode is then stored in the browser's Local Storage. It is also stored on the cookie if the cookie was absent or if its value differs from the defined identifier. Note that if values match, we do not set the cookie from JavaScript, to leave intact a cookie that may have been set on the server-side (important for ITP purposes).

    When Kameleoon is only used on the front-end, this means that visitorCode identifiers are always assigned randomly in the JavaScript engine. But if it is used on both sides, the JS engine can also obtain the identifier from a cookie passed from the back-end. This allows the identifier to be set by the server, rather than in the front-end.

    Server-side

    On the back-end, several options are available to synchronize the visitorCode:

    In any case, the following logic is implemented:

    1. First we check if a kameleoonVisitorCode cookie or query parameter associated with the current HTTP request can be found. If so, we will use this as the visitor identifier.

    2. If no cookie / parameter is found in the current request, we either randomly generate a new identifier, or use the given argument as identifier if it is passed. This allows our customers to use their own identifiers as visitor codes, should they wish to. This can have the added benefit of matching Kameleoon visitors with their own users without any additional look-ups in a matching table.

    3. In any case, the server-side (via HTTP header) kameleoonVisitorCode cookie is set with the value. If using the SDK, this identifier value is also returned by the method.

    Conclusions and remarks

    By following this approach, the visitorCode is coherently saved and shared between front-end and back-end, and cross-domain and ITP restrictions are also correctly taken into account. If an experiment is implemented on the first page of a visitor's journey on your website, the back-end will generate the identifier and pass it to the front. If the journey starts on a page where obtainVisitorCode() is not called (or the synchronization snippet is not ran) on the back-end, then the front-end will generate the identifier first, pass it to the back-end, which will read it and then rewrite it as a server-side cookie to bypass ITP restrictions.

    Cross-domain problems are also automatically treated. The only difficult case consists in a change of top-level domain with a server-side triggered experiment on the first page of the new top-level domain. In this setup, the cookie associated with the previous domain cannot be read on the new domain, and the Kameleoon JS engine won't have had the opportunity to run and restore the identifier from the Local Storage yet. So, if possible, you should pass the visitor code as a kameleoonVisitorCode HTTP query parameter from the old domain to the new one. Another solution is to wait until Kameleoon's JavaScript engine has run once on the new domain before accessing server-side SDK methods.

    Linking server-side experiments with front-end tracking code

    Often, it can be useful to setup an experiment where the implementation of variations is done on the back-end, but the tracking part is done on the front-end. This is a common situation because Web Analytics platforms (such as Google Analytics) tend to be implemented on the front-end, as well as Kameleoon tracking code. To make sure you can track and analyze your server-side experiments via your front-end tagging plan (with all your usual KPIs / goals), you need to link your server-side experiments with the front-end.

    To do that, you should first choose "Hybrid" as the test type when creating your experiment in our interface. This will ensure the experiment is correctly recognized and injected both into the client-side and server-side. Then there are two issues to take into account: the targeting / triggering of the experiment and the variation allocation.

    Ensuring correct triggering on the front-end

    Our front-end engine needs to know whenever an experiment has taken place in the back-end, ie when a visitor has been funneled into an experiment. This is important in order to count only visitors that have actually seen / triggered the experiment. There are two ways to achieve this:

    1. You can provide the correct targeting segment for the front-end part. This is usually done using our application's user interfaces (Segment Builder), but can also be setup using the Automation API. The front-end targeting conditions should exactly match the triggering conditions on the back-end. This could be quite tricky, depending on your site and the exact experiment you are running. If it's difficult to establish a proper equivalence, it's recommended to proceed with the second method instead.
    window.kameleoonQueue = window.kameleoonQueue || [];
    const experimentID = 1; // this value must be correctly entered and corresponds to the experiment's ID in Kameleoon
    window.kameleoonQueue.push(['Experiments.trigger', experimentID, true]); // onlyTracking = true, which means we only activate the experiment's tracking. This is usually what we want with hybrid experiments.
    
    1. You can take advantage of the Kameleoon Command Queue and the Activation JavaScript API to trigger the experiment explicitely, as shown in the example on the right. This JavaScript snippet must be generated by the back-end side, where the experiment's triggering code is written. It can be for example embedded in the returned HTML page.

    Ensuring correct variation allocation on the front-end

    Obviously, the same variation the user was subject to on the server-side should be registered when the experiment is triggered on the client-side. Since variation allocation is computed from the Kameleoon visitorCode, if you followed the recommendations outlined earlier to synchronize the visitorCode between the back-end and front-end, you don't have to do anything else. The visitor will have the same identifier on both sides, so will also get the same variation automatically assigned (for a given experiment).

    window.kameleoonQueue = window.kameleoonQueue || [];
    const experimentID = 1; // this value must be correctly entered and corresponds to the experiment's ID in Kameleoon
    const variationID = 3; // this value must be correctly entered and usually corresponds to the value returned by the trigger() method
    window.kameleoonQueue.push(['Experiments.assignVariation', experimentID, variationID]);
    window.kameleoonQueue.push(['Experiments.trigger', experimentID, true]); // onlyTracking = true, which means we only activate the experiment's tracking. This is usually what we want with hybrid experiments.
    

    If you don't ensure proper user identification consistency between the back-end and the front-end (although you should), or if you want to be extra careful, you can use the Kameleoon Command Queue and another Activation API method to explicitely set the variation, as outlined in the sample code on the right. This JavaScript snippet must be generated by the back-end side, where the experiment's triggering code is written. It can be for example embedded in the returned HTML page.