Skip to main content

Unify session data across subdomains

Kameleoon allows you to unify the session data across all of your subdomains. In this mode, Kameleoon tracks visitors across multiple subdomains within the same top-level domain. For example, Kameleoon can record in local storage a visit that started on one of your subdomains and continued on another subdomain as a single visit. Enabling this option is recommended if you want to use session data across all your subdomains for advanced behavioral targeting in personalization campaigns. This unifies the data stored in the local storage for all subdomains.

If you choose an implementation tag that does not support unified session data, a visit that starts in one subdomain is tracked on the user device local storage as a new visit once it reaches another subdomain. This means that all data gathered on one subdomain (such as page views, time spent on site, etc.) is reset on the new subdomain. As a result, targeting based on these types of criteria can produce unexpected results when unified session data is not enabled. For example, if you have a personalization campaign that triggers at the fourth page viewed, a visitor who sees three pages on your first domain and loads a fourth page on one of your subdomain websites will trigger the personalization only if session data is unified.

note

Data collected for analytics is not impacted by local storage partitioning on different subdomains. You need this option only if you intend to run campaigns that span across subdomains and/or that use data stored locally across different subsomains.

Availability:

Unified session data is not supported on Safari browsers due to Local Storage Partitioning restrictions. To address this, Kameleoon provides a fetching mechanism using a Server Synchronization Call. Using this method, Kameleoon obtains the visitorCode from the (server set) kameleoonVisitorCode cookie. Kameleoon then checks to see if the current LocalStorage visitorCode is empty. If it is empty, Kameleoon performs a Server Synchronization Call (SSC) that fetches all the data that was present in LocalStorage from the Kameleoon backend servers. Once this call is complete, the data is restored to its previous state.

note

This option is enabled by default on the Safari browser.

Unified session data tracking tag

To enable unified session data in Kameleoon, you must host an <iframe> file (provided below) on your website's main (top-level) domain. This iframe loads whenever a visitor navigates to a page with a URL that does not match the main domain of the website. The iframe HTML file is small, static, and contains only immutable code that is used to save and restore visitor data in Local Storage.

note

We recommend that you fetch the original file at this URL https://developers.kameleoon.com/resources/iframe_template.html. You can also download the file directly (right-click on the link and select Save link as... in your browser).

Inside the iframe code, you need to modify two variables (follow the comments inside the file to do so):

caution

To ensure optimal performance, set up caching for the iframe file. Since the file remains static and does not change, there is no need for the browser to download it multiple times. To achieve this, configure caching on the server using the following HTTP header: Cache-Control: max-age=2592000

In addition to hosting the iframe, you also need to include the following installation snippet provided below. Make sure to provide the correct value for the kameleoonIframeURL variable in the implementation code. This variable should be set to the URL where the iframe is accessible on your own website.

<script>
// Change the value of this URL to point to your own URL, where the iFrame is hosted
window.kameleoonIframeURL = "https://www.customerdomain.com/path/to/kameleoon-iframe.html";

window.kameleoonLightIframe = false;
var kameleoonIframeOriginElement = document.createElement("a");
kameleoonIframeOriginElement.href = kameleoonIframeURL;
window.kameleoonIframeOrigin = kameleoonIframeOriginElement.origin || (kameleoonIframeOriginElement.protocol + "//" + kameleoonIframeOriginElement.hostname);
if (location.href.indexOf(window.kameleoonIframeOrigin) != 0) {
window.kameleoonLightIframe = true;
var kameleoonProcessMessageEvent = function(event) {
if (window.kameleoonIframeOrigin == event.origin && event.data.slice && event.data.slice(0,9) == "Kameleoon") {
window.removeEventListener("message", kameleoonProcessMessageEvent);
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", kameleoonProcessMessageEvent, false);
}
var iframeNode = document.createElement("iframe");
iframeNode.src = kameleoonIframeURL;
iframeNode.id = "kameleoonExternalIframe";
iframeNode.style = "float: left !important; opacity: 0.0 !important; width: 0px !important; height: 0px !important;";
document.head.appendChild(iframeNode);
}
</script>
note

It is essential that you host the iframe file on your servers in the main domain of your website. If you have multiple subdomains, choose the most significant one. Your technical team must carry out this mandatory step. Technically, Kameleoon always uses your main domain to store content in the browser's Local Storage. If the current URL matches the main domain, the Kameleoon engine can directly write data to the associated Local Storage space. However, if the URL belongs to another domain, Kameleoon loads the iframe file, which contains static code that can only read and write Kameleoon data on the main domain.

note

You can use the unified session data snippet in a Tag Manager installation.

Unified tag with anti-flicker

If you use the unified 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 sesssion data script.
  3. Kameleoon installation tag.
<script>
// 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);
}

</script>
<script>
// Change the value of this URL to point to your own URL, where the iFrame is hosted
window.kameleoonIframeURL = "https://www.customerdomain.com/path/to/kameleoon-iframe.html";

window.kameleoonLightIframe = false;
var kameleoonIframeOriginElement = document.createElement("a");
kameleoonIframeOriginElement.href = kameleoonIframeURL;
window.kameleoonIframeOrigin = kameleoonIframeOriginElement.origin || (kameleoonIframeOriginElement.protocol + "//" + kameleoonIframeOriginElement.hostname);
if (location.href.indexOf(window.kameleoonIframeOrigin) != 0) {
window.kameleoonLightIframe = true;
var kameleoonProcessMessageEvent = function(event) {
if (window.kameleoonIframeOrigin == event.origin && event.data.slice && event.data.slice(0,9) == "Kameleoon") {
window.removeEventListener("message", kameleoonProcessMessageEvent);
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", kameleoonProcessMessageEvent, false);
}
var iframeNode = document.createElement("iframe");
iframeNode.src = kameleoonIframeURL;
iframeNode.id = "kameleoonExternalIframe";
iframeNode.style = "float: left !important; opacity: 0.0 !important; width: 0px !important; height: 0px !important;";
document.head.appendChild(iframeNode);
}
</script>
<script src="//SITE_CODE.kameleoon.io/kameleoon.js" fetchpriority="high" async></script>
note

If you are unable to host an iframe, Kameleoon provides a mechanism called Server Synchronization Call (SSC). This feature fetches all visitor data from Kameleoon backend servers when a visitor moves from your main domain to a sub-domain. After the call, the data is stored in the browser's Local Storage for targeting purposes. To enable this option, please contact your Customer Success Manager. It's important to note that using SSC may increase the likelihood of flickering in experiments, as the Kameleoon engine waits for the data to become available. In such cases, we recommend implementing the Unified tag with anti-flicker functionality.

Unified session data vulnerability

When using a setup with unified session data, a potential minor security issue can arise. Since all Kameleoon visitor data is written in local storage belonging to an external domain, a malicious website could potentially read this data by including your iframe in their page. Once loaded, the iframe would always return the Kameleoon data using a postMessage() call. This could potentially include custom data that you have set up, which could contain confidential or sensitive information.

note

This exploit is limited to visitors who first visit your website and then visit the malicious site, so it is a front-end exploit. Therefore, it is not possible for an attacker to obtain data for all your visitors. Nevertheless, you can enhance security by restricting access to the iframe to a specified list of domains and subdomains, including your own. This list must be provided in the allowedDomains variable within the static iFrame file.

To enhance the security of the Kameleoon iframe, we have implemented the following three measures:

  1. Restricting access to identified domains: The iframe code includes an allowedDomains variable that specifies which domains are authorized to request the iframe. Only the domains listed in this variable can load and execute code from the Kameleoon iframe. This ensures that the iframe cannot load or execute outside of your own domains.

  2. Restricting access to identified site codes: The iframe code also includes a siteCode variable that ensures only a Kameleoon engine with the specified site code is permitted to request the iframe.

  3. Prefixed Local Storage: The iframe (and Kameleoon in general) can only read and write entries that begin with the prefix "kameleoon". No other data can be read or written, adding an extra layer of security.

note

To enable unified session data through Kameleoon, it is necessary for the Kameleoon iframe to load on all of your domains. Therefore, do not set an X-Frame-Options response header.

note

Note: The domain for your Kameleoon scripts may vary from one project to another. Your projects may be hosted on either kameleoon.eu or kameleoon.io depending on their creation date. Make sure you use the domain displayed in your project in the Kameleoon App.