Skip to main content

FAQ

This list is regularly updated with recent and common questions we regularly receive from our customers.

What are the Kameleoon domains that I need to whitelist?

If your website restricts the loading of resources (scripts, images, media, CSS) via the standard Content-Security-Policy HTTP header, you'll need to update your site's Content Security Policies (CSP) to allow Kameleoon resources to load.

Easy setup (with wildcards)

This is the recommended setup. Below is the additional content for the CSP header. Add it to your own configuration.

default-src https://*.kameleoon.com https://[your-site-code].kameleoon.eu https://*.kameleoon.io;

Complete setup (fully detailed)

We strongly recommend using the easy setup as we regularly add new features to our product, which could result in additional URLs. However, if you prefer to list all of the possible hosts and resource types (script, image, etc) explicitly, add this additional content to the CSP header. Replace [your-site-code] with your Kameleoon site code in each line that it appears and add this to your configuration:

script-src https://[your-site-code].kameleoon.eu https://static.kameleoon.com https://client-config.kameleoon.com 'unsafe-eval';
style-src 'unsafe-inline';
connect-src https://[your-site-code].kameleoon.eu https://static.kameleoon.com https://data.kameleoon.io https://na-data.kameleoon.io https://editor.kameleoon.com https://api.kameleoon.com https://customers.kameleoon.com https://logger.kameleoon.eu https://client-config.kameleoon.com;
img-src https://[your-site-code].kameleoon.eu https://storage.kameleoon.eu https://static.kameleoon.com;

Why does the Kameleoon engine (kameleoon.js application file) use the eval() function?

The Kameleoon JavaScript engine requires the eval() function to allow you to add custom code to our product, such as custom data and custom JavaScript, when implementing variations of a page. Using the eval() function allows us to dynamically execute this custom code at runtime.

If you use a Content Security Policy (CSP) directive that prevents the use of the eval() function, you can implement the following JavaScript snippet before our installation tag:

<script>
window.kameleoonQueue = window.kameleoonQueue || [];

function excludeKameleoonEval() {
Kameleoon.Utils.runProtectedScript = function (code, fileName) {

let script = document.createElement("script");
script.innerHTML = code;
if (fileName) {
script.innerHTML += "//# sourceURL=" + fileName;
}
document.head.appendChild(script);
};
}

kameleoonQueue.push({
level: "IMMEDIATE",
command: excludeKameleoonEval
});
</script>

//Add the Kameleoon Installation tag here. Refer to this documentation: https://developers.kameleoon.com/web-experimentation/simple-implementation
<script src="//SITE_CODE.kameleoon.eu/kameleoon.js" async></script>

The Kameleoon Graphic Editor also requires the eval() function. However, you can work around this by installing the Kameleoon Chrome Extension and enabling the Dev Tools > Tag injection > Bypass policies setting to override the policies locally. You also need to provide your sitecode. Enabling the Bypass policies setting allows you to use the Graphic Editor using a Chrome browser. Bypass policies setting in the Chrome extension

Some features of Kameleoon are not available if the `eval()`` function is blocked with a CSP directive. These include the following features:

  • Targeting a segment with a custom JavaScript condition.
  • Using custom data with custom JavaScript code.
  • Using acquisition channels with custom JavaScript code.

Does Kameleoon offer “on-premise” tracking request URLs?

Yes, Kameleoon offers "on-premise" tracking request URLs as a premium option. This feature is particularly useful if a significant portion of your website visitors use an ad-blocker, as some ad-blocking software can block the Kameleoon script and tracking URLs.

Here's how it works: on your server, you need to forward all HTTP requests received to [na-]data.kameleoon.io. For example, if you chose tracking.yourdomain.com as your tracking domain, a tracking request would be a POST to "tracking.yourdomain.com". Your server listening on this domain should then forward the request, along with all the necessary data and parameters, to the [na-]data.kameleoon.io host.

You also need to self-host our application file.

By activating "on-premise" tracking request URLs and self-hosting our application file, you can ensure that Kameleoon's tracking works seamlessly, even if some of your users have adblockers enabled.

caution

When forwarding the requests to [na-]data.kameleoon.io, you need to make sure the URL of the request is also rewritten to [na-]data.kameleoon.io. It's not enough to just forward your request to our server while keeping the original Host: HTTP header set to your domain (tracking.yourdomain.com). Host: header must be set to [na-]data.kameleoon.io.

Can I use Subresource Integrity (SRI) with the Kameleoon application file (script or iframe)?

Unfortunately, no. While we like the idea of SRI and believe it is a good security feature in modern browsers, our application file changes over time. If it did not, we would not be able to provide many of the features Kameleoon is known for. For example, we would lose the ability to start and stop experiments instantly, without requiring a redeployment of the customer's web platform. Since the contents of our file changes, so does the hash of this resource, which means SRI cannot be used. Otherwise, it would block our resource as soon as it changes on our servers.

With Kameleoon, on Firefox only, my website now loads with a huge flash/flicker effect. Why?

It's an known bug on Firefox. Until it's fixed properly by the Firefox team, there is a workaround: your linked CSS ressource should be followed by a <script> tag (even an almost empty one). Example:

<link href="https://www.example.com/web/style.css" media="all" rel="stylesheet" type="text/css" />
<script>/**/</script>

This will remove the flashing effect entirely.

Can I use minified versions of the installation tags?

You can but our scripts are already very short and using a minified version won't meaningfully affect the loading time of your web pages (remember that this code should already be compressed using Brotli or Gzip compression). Thus we do not recommend the use of minified versions. However, if you still want to use them, you can find them below.

Asynchronous loading with anti-flicker

<script>
var a=1000;window.kameleoonQueue=window.kameleoonQueue||[];window.kameleoonStartLoadTime=new Date().getTime();if(!document.getElementById("kameleoonLoadingStyleSheet")&&!window.kameleoonDisplayPageTimeOut){var b=document.getElementsByTagName("script")[0];var c="* { visibility: hidden !important; background-image: none !important; }";var d=document.createElement("style");d.type="text/css";d.id="kameleoonLoadingStyleSheet";if(d.styleSheet){d.styleSheet.cssText=c}else{d.appendChild(document.createTextNode(c))}b.parentNode.insertBefore(d,b);window.kameleoonDisplayPage=function(e){if(!e){window.kameleoonTimeout=true}if(d.parentNode){d.parentNode.removeChild(d)}};window.kameleoonDisplayPageTimeOut=window.setTimeout(window.kameleoonDisplayPage,a)};
</script>
<script src="//SITE_CODE.kameleoon.eu/kameleoon.js" async></script>

Unify session data across subdomains

If you use the unified session data tag to unify session data across subdomains with either the synchronous tag or the asynchronous tag without antiflicker:

<script>
window.kameleoonIframeURL="https://www.customerdomain.com/path/to/kameleoon-iframe.html";var f=document.createElement("a");window.kameleoonLightIframe=false;f.href=window.kameleoonIframeURL;window.kameleoonIframeOrigin=f.origin||(f.protocol+"//"+f.hostname);if(location.href.indexOf(window.kameleoonIframeOrigin)!=0){window.kameleoonLightIframe=true;var g=function(event){if(window.kameleoonIframeOrigin==event.origin&&event.data.slice&&event.data.slice(0,9)=="Kameleoon"){window.removeEventListener("message",g);window.kameleoonExternalIFrameLoaded=true;if(window.Kameleoon){Kameleoon.Utils.runProtectedScript(event.data);Kameleoon.Analyst.load()}else{window.kameleoonExternalIFrameLoadedData=event.data}}};if(window.addEventListener){window.addEventListener("message",g,false)}var h=document.createElement("iframe");h.src=kameleoonIframeURL;h.id="kameleoonExternalIframe";h.style="float: left !important; opacity: 0.0 !important; width: 0px !important; height: 0px !important;";document.head.appendChild(h)};
</script>

If you use the unified session data tag to unify session data across subdomains and the asynchronous tag with anti-flicker, you must add the three script tags in the following order:

  1. Asynchronous tag with anti-flicker.
  2. Unified session data tag.
  3. Kameleoon installation tag.
<script>
var a=1000;window.kameleoonQueue=window.kameleoonQueue||[];window.kameleoonStartLoadTime=new Date().getTime();if(!document.getElementById("kameleoonLoadingStyleSheet")&&!window.kameleoonDisplayPageTimeOut){var b=document.getElementsByTagName("script")[0];var c="* { visibility: hidden !important; background-image: none !important; }";var d=document.createElement("style");d.type="text/css";d.id="kameleoonLoadingStyleSheet";if(d.styleSheet){d.styleSheet.cssText=c}else{d.appendChild(document.createTextNode(c))}b.parentNode.insertBefore(d,b);window.kameleoonDisplayPage=function(e){if(!e){window.kameleoonTimeout=true}if(d.parentNode){d.parentNode.removeChild(d)}};window.kameleoonDisplayPageTimeOut=window.setTimeout(window.kameleoonDisplayPage,a)};
</script>
<script>
window.kameleoonIframeURL="https://www.customerdomain.com/path/to/kameleoon-iframe.html";var f=document.createElement("a");window.kameleoonLightIframe=false;f.href=window.kameleoonIframeURL;window.kameleoonIframeOrigin=f.origin||(f.protocol+"//"+f.hostname);if(location.href.indexOf(window.kameleoonIframeOrigin)!=0){window.kameleoonLightIframe=true;var g=function(event){if(window.kameleoonIframeOrigin==event.origin&&event.data.slice&&event.data.slice(0,9)=="Kameleoon"){window.removeEventListener("message",g);window.kameleoonExternalIFrameLoaded=true;if(window.Kameleoon){Kameleoon.Utils.runProtectedScript(event.data);Kameleoon.Analyst.load()}else{window.kameleoonExternalIFrameLoadedData=event.data}}};if(window.addEventListener){window.addEventListener("message",g,false)}var h=document.createElement("iframe");h.src=kameleoonIframeURL;h.id="kameleoonExternalIframe";h.style="float: left !important; opacity: 0.0 !important; width: 0px !important; height: 0px !important;";document.head.appendChild(h)};
</script>
<script src="//SITE_CODE.kameleoon.eu/kameleoon.js" async></script>

Can I modify the installation tag Kameleoon provides?

You should not modify the installation tags we provide. Their code has been extensively tested and optimized. Customers have modified them in the past only to end up with a non-working setup. If for any reason you think you need to modify your installation tag, please contact your Kameleoon Account Manager who will put you in touch with our developers to assist with this task. We strongly recommended that you do not to attempt this on your own.

Can I add the installation tag in a separate external script?

You should not include any installation tag in its own separate, external script. For example, never do this:

<script src="resources/scripts/kameloon-loader.js"></script>

while the kameloon-loader.js script contains for instance the following installation code:

// Duration in milliseconds to wait while the Kameleoon application file is loaded
var kameleoonLoadingTimeout = 1000;

window.kameleoonQueue = window.kameleoonQueue || [];
window.kameleoonStartLoadTime = new Date().getTime();

if (!document.getElementById("kameleoonLoadingStyleSheet") && !window.kameleoonDisplayPageTimeOut) {
var kameleoonS = document.getElementsByTagName("script")[0];
var kameleoonCc = "\* { visibility: hidden !important; background-image: none !important; }";
var kameleoonStn = document.createElement("style");
kameleoonStn.type = "text/css";
kameleoonStn.id = "kameleoonLoadingStyleSheet";

if (kameleoonStn.styleSheet) {
kameleoonStn.styleSheet.cssText = kameleoonCc;
} else {
kameleoonStn.appendChild(document.createTextNode(kameleoonCc));
}

kameleoonS.parentNode.insertBefore(kameleoonStn, kameleoonS);
window.kameleoonDisplayPage = function(fromEngine) {
if (!fromEngine) {
window.kameleoonTimeout = true;
}

if (kameleoonStn.parentNode) {
kameleoonStn.parentNode.removeChild(kameleoonStn);
}
};

window.kameleoonDisplayPageTimeOut = window.setTimeout(window.kameleoonDisplayPage, kameleoonLoadingTimeout);
}

var scriptNode = document.createElement("script");
scriptNode.src = "//SITE_CODE.kameleoon.eu/kameleoon.js";
scriptNode.type = "text/javascript";
scriptNode.async = true;
document.head.appendChild(scriptNode);

While this may technically work, this significantly affect the performance of Kameleoon and introduce a noticeable flicker effect. This is like implementing your own tag manager by doing that: you will suffer all the problems of using a tag manager without any of the associated benefits. Please, really, don't do it.

Is it possible to encrypt data in case of dedicated data-storage clusters (on-premises setup)?

Yes, we can encrypt the partitions where the data will be stored. This option requires an additional setup cost. Contact your Customer Success Manager.

Can I delay non-essential experiments until after the first page load?

Yes, our web experimentation product allows you to delay non-essential experiments until after the first page load. To delay an experiment, add the DELAYED tag to all experiments you want to defer. For more information, see the managing tags documentation.

Experiments tagged as "DELAYED" are intelligently managed. Kameleoon doesn't download the configuration until an idle time of at least 10 seconds after the initial page load elapses or until the visitor is being targeted and allocated with a variant that is not the control (reference) variant.

By using this feature, you can focus on delivering the best user experience, as resource-intensive tests won't cause delays or disruptions during the critical page load phase.

Which databases and frameworks does Kameleoon use?

Currently, we use the following NoSQL databases and technologies in our data flow architecture:

  • Hadoop File System (along with Spark)
  • Cassandra
  • ClickHouse
  • Kafka

What network requests does the Kameleoon engine make?

The Kameleoon engine initiates several network requests to ensure seamless functionality. Here are the main requests:

Segments Request:

  • Purpose: Collects events for targeted segments by the visitor.
  • Endpoint: https://${SITECODE}.kameleoon.eu/audiences/segments.js
  • Method: GET
  • Note: The file is cached for 90 minutes.

Live-update Experiments Configuration Request:

  • Purpose: Retrieves LIVE-UPDATE tagged experiments configuration.
  • Endpoint: https://${SITECODE}.kameleoon.eu/live-experiments/config.js
  • Method: GET
  • Note: The file is cached for 1 minute.

Deferred Experiment Variation Request:

  • Purpose: Loads variation data for DELAYED tagged experiments.
  • Endpoint: https://${SITECODE}.kameleoon.eu/experiments/${action.id}/variations/${variationId}.js
  • Method: GET
  • Note: The file is cached for 30 days.

Deferred Personalization Variation Request:

  • Purpose: Loads variation data for DELAYED tagged personalizations.
  • Endpoint: https://${SITECODE}.kameleoon.eu/personalizations/${action.id}/variations/${variationId}.js
  • Method: GET
  • Note: The file is cached for 30 days.

Previous Visits Request:

Tracking Events Request:

IP address Request:

  • Purpose: Exclusively for targeting purposes, enabling the exclusion/inclusion of visitors based on their IP Address.
  • Endpoint: https://data.kameleoon.io/ip
  • Method: GET
  • Note: Kameleoon never stores IPs in our databases nor uses them for analytics. The user's IP is employed solely for comparison to an exclusion/inclusion list within the visitor's browsers.

Geolocation Request:

Kameleoon Script Detection Request:

Products Request:

Kameleoon Conversion Scores Request: