Skip to main content

Hybrid experimentation

Kameleoon can be operated in hybrid mode, using both server-side SDKs and the Kameleoon JavaScript application file. This allows you to use the optimal approach for individual tasks. For example, you can implement and deploy variations more easily on the server-side, while tracking can be performed more effectively with the Javascript file (since many third-party web analytics solutions only work on the front-end).

Kameleoon provides native integrations with analytics or CDPs platforms, and in hybrid mode, you can use any integration in combination with server-side experiments, without needing to write additional code.

This article describes how to implement an optimal integration between the Kameleoon server-side SDK and the Kameleoon front-end application file, 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.


To ensure the reliable performance of Kameleoon on Safari browsers, we now recommend implementing a back-end/front-end bridge for ITP management, even if you do not directly use Kameleoon Feature Experimentation. This allows to you overcome Intelligent Tracking Prevention (ITP) limitations so that Kameleoon functions seamlessly.

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

To benefit from client-side capabilities on top of server-side experiments, you will need to implement both our SDK and our Kameleoon JavaScript tag. We recommend you implement the Kameleoon Asynchronous tag, which you can install at the end of your body tag, as it will be only used for tracking purposes.

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.

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

  1. On the front-end side, a visitorCode is randomly generated and assigned for every new visitor by our JavaScript engine. A visitor is technically considered a new visitor if no previous visitorCode can be found for this user. This usually happens when the Kameleoon engine is run for the first time on the visitor's browser. The Kameleoon 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.

If you use Kameleoon Cross-Domain Tracking, Kameleoon checks if a kameleoonVisitorCode key exists in local storage. If the key is present, its value is used as the identifier for the visitor code. The local storage version of this key always takes precedence, even if a kameleoonVisitorCode cookie with a different value exists. Note that Kameleoon does not reset the cookie from JavaScript if the local storage and cookie values match. For ITP purposes, leaving cookies that may have been set on the server side intact is important.

  1. On the back-end, you need to use the getVisitorCode() method available in all our server-side SDKs. Make sure to call this method every time you need to obtain a visitor identifier before using any other SDK methods. The getVisitorCode() takes an optional string argument that you can use to pass your own identifier rather than rely on a randomly generated Kameleoon ID. When the method is called, Kameleoon first looks for a kameleoonVisitorCode cookie or query parameter associated with the current HTTP request. If found, the SDK uses this as the visitor identifier.

If no cookie or parameter is found, Kameleoon uses the getVisitorCode() method argument, if you provided one, as the identifier. If you don't provide an argument, Kameleoon randomly generates the ID. In either of these cases, Kameleoon also sets the server-side kameleoonVisitorCode cookie with the value (via HTTP header).


If you don't use an SDK, there are other other methods you can use to perform the synchronization, such as adding a code snippet on your backend server. See the synchronization options in the Advanced implementation guide.

By following this approach, the visitorCode is coherently saved and shared between front-end and back-end. 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 getVisitorCode() 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.

Linking server-side experiments with front-end tracking code (Hybrid Experimentation)

It is often useful to set up an experiment where you implement variations on the back-end by using an SDK, but you implement tracking on the front-end by using a JavaScript engine. This is a common situation because web analytics platforms (such as Google Analytics) tend to be implemented on the front-end, as is the 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 and goals), you need to link your server-side experiments with the front-end.


If you follow these guidelines, and you already use a standard client-side tagging plan for Kameleoon, then you don't even need to implement conversion calls on the back-end when using server-side experiments (although this can still be useful). Goals and conversions will be tracked via the front-end and will appear automatically in Kameleoon reports. This will also allow you to get experiment results in any Web Analytics solution with an integration to Kameleoon (Adobe Analytics, GA4, Mixpanel, Amplitude, etc).

To link your server-side experiments with the front end, you need to configure triggering as described in the following section.

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 bucketed into an experiment. This is important in order to count only visitors that have actually seen / triggered the experiment. To achieve this, you need to use the getEngineTrackingCode() method available in all our server-side SDKs. This method returns the JavaScript code to be inserted in your page to automatically send the exposure events from the front-end to the analytics solution you are using. It can be embedded in the returned HTML page.

For example:

<!DOCTYPE html>
<html lang="en">
const engineTrackingCode = `
window.kameleoonQueue = window.kameleoonQueue || [];
window.kameleoonQueue.push(['Experiments.assignVariation', 123456, 7890]);
window.kameleoonQueue.push(['Experiments.trigger', 123456, true]);
const script = document.createElement('script');

script.textContent = engineTrackingCode;

You also need to activate the integration of your choice (GA4, Mixpanel...) when configuring your feature experiment. The relevant data (experiment ID, experiment Name, variation ID, variation Name) will then be automatically sent to the third party platform by the Kameleoon JavaScript engine.