Skip to main content

React / React Native SDK

Introduction

Welcome to the developer documentation for the Kameleoon React SDK! Our SDK gives you the possibility of running experiments and activating feature flags on your front-end web and mobile application. Integrating our SDK into your web and mobile application is easy, and its footprint (in terms of memory and network usage) is low.

note

Before you begin installing our React SDK, we recommend that you read our technical considerations article to gain an understanding of the fundamental technological concepts behind our SDKs. This will help you to better understand the SDK and ensure a successful integration.

The React SDK offers versatile functionality that can be leveraged for both React and React Native applications. While the majority of the hooks function in a consistent manner across both platforms, it should be noted that React Native employs a distinct mechanism for storing feature flag related data. Specifically, React Native utilizes the MMKV storage mechanism rather than the localStorage approach utilized by browsers.

note

To ensure seamless integration between your React Native application and the React SDK, it is highly recommended to review the React Native Considerations section. This section provides essential guidance for optimizing compatibility and ensuring proper functionality.


Changelog

Latest version description of React SDK can be found here.


Requirements

React SDK requires React 16.8.0+


Installation

Use preferred package manager to install React SDK from npm repository.

Npm:

npm install @kameleoon/react-sdk

Yarn:

yarn add @kameleoon/react-sdk

Pnpm:

pnpm add @kameleoon/react-sdk

Contents

To configure your React application and start running feature experiments and deploying new features to your users, please follow the instructions provided in the Main usage section. This section contains all the main steps for proper Kameleoon React SDK configuration as well as main tools for development.

  1. Create Kameleoon Client
  2. Wrap application in Kameleoon Provider
  3. Await for client initialization
  4. Getting access to feature flags and variations
  5. Using Kameleoon CLient hooks
note

In addition to using Kameleoon’s React SDK to roll out new features and define advanced delivery rules with our Feature Management & Experimentation solution, you can also leverage this SDK for running server-side and hybrid experiments (without utilizing feature flags). For more information on configuring these experiments, please refer to the useTriggerExperiment hook.

We highly recommend that you take a look at the Additional Tools section, which includes useful information on every hook that is introduced in React SDK.

Explore additional sections with some useful information on Kameleoon Data types, React Native Consideration where dedicated hook is displayed and Error handling.


Migration

We have introduced new version of React SDK with the breaking changes.

Migration considerations

  • All HOCs, Feature render props, compose were removed.
  • All data types hooks were removed: useDevice, useConversion, useCustomData, usePageView, useBrowser.

Removed hooks:

  • useRunWhenReady (no longer needed, use useInitialize instead)
  • useFeature

Renamed hooks:

Added hooks:


Main Usage

Here is a step by step guide for configuring React JS SDK for your application.

1. Create Kameleoon Client

createClient

import { createClient, Environment } from '@kameleoon/react-sdk';

const client = createClient('my_site_code', {
updateInterval: 60,
environment: Environment.Production,
});

For the start developers will need to create an entry point for React SDK by creating Kameleoon Client on the top level of your application which is done by using createClient() function imported from kameleoon package.

An instance of KameleoonClient is created using createClient() function.

Parameters
NameTypeDescription
siteCode (required)stringclient's siteCode defined on Kameleoon platform
configuration (optional)Partial<SDKConfigurationType>client's configuration
note

configuration consists of following parameters:

NameTypeDescriptionDefault Value
updateInterval (optional)numberupdate interval in minutes for sdk configuration, minimum value is 1 minute60
environment (optional)Environmentfeature flag environmentEnvironment.Production
targetingDataCleanupInterval (optional)number or undefinedinterval in minutes for cleaning up targeting data, minimum value is 1 minuteundefined (no cleanup will be performed)
Returns

KameleoonClient - an instance of KameleoonClient.

note

Make sure not to use several client instances in one application with different environment as it is not fully supported yet, which may lead to local storage configuration being overwritten and cause bugs.

2. Wrap application in Kameleoon Provider

The second step is connecting previously created Kameleoon Client to KameleoonProvider. It can be done by passing configured client to KameleoonProvider as follows.

import {
createClient,
Environment,
KameleoonProvider,
} from '@kameleoon/react-sdk';

const client = createClient('my_site_code', {
updateInterval: 60,
environment: Environment.Production,
});

function AppWrapper(): JSX.Element {
return (
<KameleoonProvider client={client}>
<App />
</KameleoonProvider>
);
}

KameleoonProvider

Use this provider on root level by wrapping your app to gain an access to KameleoonClient. This ensures your app does not flicker due to flag changes at startup time.

Props
NameTypeDescription
children (required)ReactNodechild elements of the provider
client (required)KameleoonClientKameleoonClient instance created by createClient()

3. Await for the client initialization

KameleoonClient initialization is done asynchronously in order to make sure that Kameleoon API call was successful for that hook useInitialize is used. You can use async/await, Promise.then() or any other method to handle asynchronous client initialization.

import { useEffect, useCallback } from 'react';
import { useInitialize } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();

// -- Waiting for the client initialization using `async/await`

const init = useCallback(async (): Promise<void> => {
await initialize();
}, [initialize]);

useEffect(() => {
init();
}, [init]);
}

4. Getting access to feature flags and variations

note

To implement a feature flag in your code, you must first create a feature flag in your Kameleoon account.

After the SDK has been initialized, you can obtain a feature flag configuration. Subsequently, all hooks will require you to specify the User ID or visitor code associated with the request.

note

If you are using Kameleoon in Hybrid mode with mixed front-end and back-end environments, you can call the useBrowserVisitorCode hook to obtain the Kameleoon visitorCode for the current visitor. Alternatively, if you provide your own User ID, you must ensure its uniqueness on your end.

5. Using Kameleoon Client hooks

Now that KameleoonClient is created, configured and added to a KameleoonProvider it is possible to communicate with your feature flag and experiments from the inside of React Components.

To associate various data points with the current user, you can use the useAddData hook. This hook returns addData function which requires the visitorCode as the first parameter and accepts several additional parameters. These additional parameters represent the various Data Types allowed in Kameleoon.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useAddData,
useBrowserVisitorCode,
useTriggerExperiment,
useTrackConversion,
useFeatureFlagActive,
CustomData,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { addData } = useAddData();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { triggerExperiment } = useTriggerExperiment();
const { trackConversion } = useTrackConversion();
const { isFeatureFlagActive } = useFeatureFlagActive();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Trigger an experiment
const experimentId = 100;
const variationId = triggerExperiment(visitorCode, experimentId);

// -- Add user data
const customDataIndex = 0;
addData(visitorCode, new CustomData(customDataIndex, 'my_data'));

// -- Check if the feature is active for visitor
const isMyFeatureActive = isFeatureFlagActive(
visitorCode,
'my_feature_key',
);

// -- Track conversion
trackConversion({ visitorCode, revenue: 20000, goalId: 123 });
}, [
initialize,
visitorCode,
triggerExperiment,
isFeatureFlagActive,
trackConversion,
]);

useEffect(() => {
init();
}, [init]);
}

Feature flags can be very useful for implementing ON/OFF switches with optional but advanced user targeting rules. However, you can also use feature flags to run feature experiments with several variations of your feature flag. Check out our documentation on creating feature experiments for more information.

note

See Additional Tools section for detailed guide for each KameleoonClient hook available.


Additional Tools

Get Visitor Code / Use Own Visitor ID

note

React SDK provides dedicated hooks for React useBrowserVisitorCode and React Native useNativeVisitorCode.

useBrowserVisitorCode

A hook that returns getBrowserVisitorCode function which obtains visitor code from browser cookie, if the visitor code doesn't yet exist generates a random visitor code (or uses a provided default) and sets a new visitor code to cookie.

import { useBrowserVisitorCode } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { getBrowserVisitorCode } = useBrowserVisitorCode();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

// -- Pass default visitorCode, save and retrieve it
const visitorCode = getBrowserVisitorCode(
'www.example.com',
'default_visitor_code',
);
Callback Parameters
NameTypeDescription
domain (required)stringdomain which cookie belongs to
defaultVisitorCode (optional)stringvisitor code to be used in case there is no visitor code in cookies
note

If defaultVisitorCode wasn't provided and there is no visitor code stored in cookie it will be randomly generated

Callback Returns

string - result visitor code.


Initialize Kameleoon Client

useInitialize

A hook that returns an asynchronous initialize function which is used for KameleoonClient initialization by fetching Kameleoon SDK related data from server or by retrieving data from local source if data is up-to-date or update interval has not been reached.

import { useEffect, useCallback } from 'react';
import { useInitialize } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();

const init = useCallback(async (): Promise<void> => {
await initialize();
}, [initialize]);

useEffect(() => {
init();
}, [init]);
}
note

Client initialization has an optional offline mode. It is activated by setting optional useCache parameter to true. Offline mode allows for silent polling fails.

If the SDK was already initialized successfully but at some point Internet connection was lost, SDK will still try to fetch next configuration when time of updateInterval comes, which can cause initialize errors, activating offline mode will prevent such errors from happening, while the latest cached experiments and feature flags data will be used as a fallback.

Activating offline mode doesn't prevent initialization from failing if there is no cached data available.

Callback Parameters
NameTypeDescriptionDefault Value
useCache (optional)boolean or undefinedparameter for activating SDK offline mode, if true is passed failed polls will not return error and will use cached data if such data is availablefalse
Callback Returns

Promise<boolean> - a promise resolved to a boolean indicating a successful sdk initialization. Generally initialize will throw an error if the something that can not be handled will happen, so the boolean value will almost always be true and won't give as much useful information.

Throws
TypeDescription
KameleoonException.StorageWriteCouldn't update storage data
KameleoonException.ClientConfigurationCouldn't retrieve client configuration from Kameleoon API
KameleoonException.MaximumRetriesReachedMaximum retries reached, request failed

Add associated client data

useAddData

A hook that returns addData function which adds targeting data to the storage so that other hooks could decide whether the current visitor is targeted or not.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
CustomData,
Browser,
BrowserType,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Create Kameleoon Data Types
const customData = new CustomData(0, 'my_data');
const browserData = new Browser(BrowserType.Chrome);

// -- Add one Data item to Storage
addData(visitorCode, browserData);

// -- Add Data to Storage using variadic style
addData(visitorCode, browserData, customData);

// -- Add Data to Storage in array
addData(visitorCode, ...[browserData, customData]);
}, [initialize, visitorCode, addData]);

useEffect(() => {
init();
}, [init]);
}
note

The addData() function does not return any value and does not interact with Kameleoon back-end servers on its own. Instead, all the declared data is saved for future transmission via the useFlushData hook .This approach helps reduce the number of server calls made, as the data is typically grouped into a single server call triggered by the execution of useFlushData.

useTriggerExperiment and useTrackConversion hooks also send out any previously associated data, just like the useFlushData. The same holds true for useFeatureVariationKey and useFeatureVariable hooks if an experimentation rule is triggered.

note

userAgent data will not be stored in storage like other data, and it will be sent with every tracking request for bot filtration.

Callback Parameters
NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length
kameleoonData (optional)KameleoonDataType[]number of instances of any type of KameleoonData, can be added solely in array or as sequential arguments
note

kameleoonData is variadic argument it can be passed as one or several arguments (see the example)

note

The index or ID of the custom data can be found in your Kameleoon account. It is important to note that this index starts at 0, which means that the first custom data you create for a given site will be assigned 0 as its ID, not 1.

Throws
TypeDescription
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded
KameleoonException.StorageWriteCouldn't update storage data
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient
note

Check Data Types reference for more details of how to manage different data types


Trigger an Experiment (without feature flags)

useTriggerExperiment

A hook that returns triggerExperiment function which triggers experiment by assigning the variation to the user with visitorCode, if the variation is already assigned just returns it's id. At the same time executes flushData without sending extra tracking request.

The triggerExperiment function allows you to run server-side or hybrid experiments without the need to configure feature flags.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useTriggerExperiment,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { triggerExperiment } = useTriggerExperiment();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

const experimentId = 123;

// -- Trigger Experiment and obtain variation id
const variationId = triggerExperiment(visitorCode, experimentId);
}, [initialize, visitorCode, triggerExperiment]);

useEffect(() => {
init();
}, [init]);
}
note

Returned id 0 indicates default variation.

Callback Parameters
NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length
experimentId (required)numberid of experiment running for the current visitor.
Callback Returns

number - associated variationId which is successfully found in storage or newly assigned.

Throws
TypeDescription
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded
KameleoonException.ExperimentConfigurationNotFoundNo configuration found for provided experimentId
KameleoonException.StorageReadCouldn't find associated experiment by provided experimentId and visitorCode inside the storage
KameleoonException.NotTargetedCurrent visitor is not targeted
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient

Track Conversion

useTrackConversion

A hook that returns trackConversion function which creates and adds Conversion data to the visitor with specified parameters and executes flushData.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useTrackConversion,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { trackConversion } = useTrackConversion();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Track conversion
trackConversion({ visitorCode, revenue: 2000, goalId: 123 });
}, [initialize, trackConversion, visitorCode]);

useEffect(() => {
init();
}, [init]);
}
note

It's a helper hook for the quick and convenient conversion tracking, however creating and adding Conversion manually allows more flexible Conversion with negativeparameter

Callback Parameters

Parameters object consisting of:

NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length
goalId (required)numbergoal to be sent in tracking request
revenue (required)numberrevenue to be sent in tracking request
Throws
TypeDescription
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded
KameleoonException.StorageWriteCouldn't update storage data

Flush tracking data

useFlushData

A hook that returns flushData function which takes visitor associated Kameleoon data and sends the data tracking request with all data added using useAddData by this point.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
useFlushData,
CustomData,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();
const { flushData } = useFlushData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Create instance of CustomData
const customData = new CustomData(0, 'my_data');
addData(visitorCode, customData);

// -- Flush added custom data
flushData(visitorCode);
}, [initialize, visitorCode, addData, flushData]);

useEffect(() => {
init();
}, [init]);
}
Callback Parameters
NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length

Get list of all experiments

useExperiments

A hook that returns getExperiments function which returns a list of experiments stored in the client configuration.

import { useEffect, useCallback } from 'react';
import { useInitialize, useExperiments } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getExperiments } = useExperiments();

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Get experiment list
const experiments = getExperiments();
}, [initialize, getExperiments]);

useEffect(() => {
init();
}, [init]);
}
Callback Returns

ExperimentType[] - list of experiments, each experiment item contains id and name.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient

Get list of experiments for a certain visitor

useVisitorExperiments

A hook that returns getVisitorExperiments function which returns a list of experiments that the visitor with visitorCode is targeted by and that are active for the visitor.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useVisitorExperiments,
useBrowserVisitorCode,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { getVisitorExperiments } = useVisitorExperiments();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Get all visitor experiments
const experiments = getVisitorExperiments(visitorCode, false);

// -- Get only allocated visitor experiments
const allocatedExperiments = getVisitorExperiments(visitorCode);
}, [initialize, visitorCode, getVisitorExperiments]);

useEffect(() => {
init();
}, [init]);
}
note

Visitor will have one of the variations allocated if the experiment was triggered

Callback Parameters
NameTypeDescriptionDefault Value
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length-
isAllocated (optional)booleanboolean value indicating that only experiments allocated for visitor will be returned.true
Callback Returns

ExperimentType[] - list of experiments, each experiment item contains id and name.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded

Get a certain experiment variation data

useExperimentVariationData

A hook that returns getExperimentVariationData function which returns variation data in JSON format for the variation with variationId.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useExperimentVariationData,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getExperimentVariationData } = useExperimentVariationData();

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Get experiment variation data
const variationId = 100;
const variationDataJson = getExperimentVariationData(variationId);
}, [initialize, visitorCode, getVisitorExperiments]);

useEffect(() => {
init();
}, [init]);
}
Callback Parameters
NameTypeDescription
variationId (required)numberid of a variation
Callback Returns

JSONType - variation data in JSON format.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient
KameleoonException.JSONParseCouldn't parse retrieved data to JSON format
KameleoonException.VariationNotFoundNo variation found for provided variationId

Get list of all feature flags

useFeatureFlags

A hook that returns getFeatureFlags function which returns a list of feature flags stored in the client configuration.

import { useEffect, useCallback } from 'react';
import { useInitialize, useFeatureFlags } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getFeatureFlags } = useFeatureFlags();

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Get list of all feature flags
const featureFlags = getFeatureFlags();
}, [initialize, getFeatureFlags]);

useEffect(() => {
init();
}, [init]);
}
Callback Returns

FeatureFlagType[] - list of feature flags, each experiment item contains id and key.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient

Get list of feature flags for a certain visitor

useVisitorFeatureFlags

A hook that returns getVisitorFeatureFlags function which returns a list of feature flags that the visitor with visitorCode that is targeted by and that are active for the visitor (visitor will have one of the variations allocated).

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useVisitorFeatureFlags,
useBrowserVisitorCode,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { getVisitorFeatureFlags } = useVisitorFeatureFlags();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Get active feature flags for visitor
const featureFlags = getVisitorFeatureFlags(visitorCode);
}, [initialize, visitorCode, getVisitorFeatureFlags]);

useEffect(() => {
init();
}, [init]);
}
Callback Parameters
NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length
Callback Returns

FeatureFlagType[] - list of feature flags, each experiment item contains id and key.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded
KameleoonException.NotTargetedCurrent visitor is not targeted

Check if the feature is active for visitor

useFeatureFlagActive

A hook that returns a callback function isFeatureFlagActive() which indicates whether the visitor with visitorCode has featureKey active for him, this includes targeting check, finding the according variation exposed to the visitor and saving it to storage along with sending tracking request.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useAddData,
useFeatureFlagActive,
useBrowserVisitorCode,
CustomData,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { addData } = useAddData();
const { isFeatureFlagActive } = useFeatureFlagActive();
const { getBrowserVisitorCode } = useBrowserVisitorCode();

// -- Get visitor code using `getBrowserVisitorCode` function
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

const featureKey = 'my_feature_key';

// -- Add CustomData with index `0` containing visitor id to check the targeting
addData(visitorCode, new CustomData(0, 'visitor_id'));

// -- Get the status of feature flag
const isActive = isFeatureFlagActive(visitorCode, featureKey);
}, [initialize, visitorCode, isFeatureFlagActive]);

useEffect(() => {
init();
}, [init]);
}
note

Visitor must be targeted to has feature flag active

Callback Parameters
NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length
featureKey (required)stringa unique key for feature flag
Callback Returns

boolean - indicator of whether the feature flag with featureKey is active for visitor with visitorCode.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded
KameleoonException.NotTargetedCurrent visitor is not targeted
KameleoonException.FeatureFlagConfigurationNotFoundNo feature flag was found for provided visitorCode and featureKey
KameleoonException.DataInconsistencyAllocated variation was found but there is no feature flag with according featureKey

Get variation key for a certain feature flag

useFeatureFlagVariationKey

A hook that returns a callback function getFeatureFlagVariationKey() which returns variation key for the visitor under visitorCode in the found feature flag, this includes targeting check, finding the according variation exposed to the visitor and saving it to storage along with sending tracking request.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useFeatureFlagVariationKey,
useBrowserVisitorCode,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getFeatureFlagVariationKey } = useFeatureFlagVariationKey();
const { getBrowserVisitorCode } = useBrowserVisitorCode();

// -- Get visitor code using `getBrowserVisitorCode` function
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

const featureKey = 'my_feature_key';

// -- Get the variationKey for the visitor under `visitorCode` in the found feature flag
const variationKey = getFeatureFlagVariationKey(visitorCode, featureKey);
}, [initialize, visitorCode, getFeatureFlagVariationKey]);

useEffect(() => {
init();
}, [init]);
}
note

If the user has never been associated with the feature flag, the SDK returns a variation key randomly, following the feature flag rules. If the user is already registered with the feature flag, the SDK detects the previous variation key value. If the user doesn't match any of the rules, the default value defined in Kameleoon's feature flag delivery rules will be returned. It's important to note that the default value may not be a variation key, but a boolean value or another data type, depending on the feature flag configuration.

Callback Parameters
NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length
featureKey (required)stringa unique key for feature flag
Callback Returns

string - a string containing variable key for the allocated feature flag variation for the provided visitor.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded
KameleoonException.NotTargetedCurrent visitor is not targeted
KameleoonException.FeatureFlagConfigurationNotFoundNo feature flag was found for provided visitorCode and featureKey

Get a variable of a certain feature flag

useFeatureVariable

A hook that returns getFeatureFlagVariable function which returns a variable for the visitor under visitorCode in the found feature flag, this includes targeting check, finding the according variation exposed to the visitor and saving it to storage along with sending tracking request.

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useFeatureVariable,
VariableType,
JSONType,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { getFeatureFlagVariable } = useFeatureVariable();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Get feature variable
const variable = getFeatureFlagVariable({
visitorCode,
featureKey: 'my_feature_key',
variableKey: 'my_variable_key',
});

// -- Infer the type of variable by it's `type`
switch (variableResult.type) {
case VariableType.BOOLEAN:
const myBool: boolean = res.value;
break;
case VariableType.NUMBER:
const myNum: number = res.value;
break;
case VariableType.JSON:
const myJson: JSONType = res.value;
break;
case VariableType.STRING:
const myStr: string = res.value;
break;
default:
break;
}
}, [initialize, getFeatureFlagVariable, visitorCode]);

useEffect(() => {
init();
}, [init]);
}
Callback Parameters

Parameters object of a type GetFeatureFlagVariableParamsType containing the following fields:

NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length
featureKey (required)stringa unique key for feature flag
variableKey (required)stringkey of the variable to be found for a feature flag with provided featureKey, can be found on Kameleoon Platform
Callback Returns

FeatureVariableResultType - a variable object containing type and value fields, type can be checked against FeatureVariableType enum, if the type is FeatureVariableType.BOOLEAN then the value type will be boolean and so on.

Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient
KameleoonException.VisitorCodeMaxLengthThe visitor code length was exceeded
KameleoonException.NotTargetedCurrent visitor is not targeted
KameleoonException.FeatureFlagConfigurationNotFoundNo feature flag was found for provided visitorCode and featureKey
KameleoonException.JSONParseCouldn't pass JSON value
KameleoonException.NumberParseCouldn't pass Number value

Obtain data from Kameleoon remote source

useRemoteData

A hook that returns asynchronous getRemoteData function which returns a data stored for specified site code on a remote Kameleoon server.

For example, you can use this function to retrieve user preferences, historical data, or any other data relevant to your application's logic. By storing this data on our highly scalable servers using our Data API, you can efficiently manage massive amounts of data and retrieve it for each of your visitors or users.

import { useEffect, useCallback } from 'react';
import { useRemoteData } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { getRemoteData } = useRemoteData();

const getData = useCallback(async (): Promise<void> => {
// -- Get remote data
const jsonData = await getRemoteData('my_data_key');

const data: MyDataType = JSON.parse(jsonData);
}, [getRemoteData]);

useEffect(() => {
getData();
}, [getData]);
}
Callback Parameters
NameTypeDescription
key (required)stringunique key that the data you try to get is associated with
Callback Returns

JSONType - promise with data retrieved for specific key.

Throws
TypeDescription
KameleoonException.RemoteDataCouldn't retrieve data from Kameleoon server

Obtain custom data from Kameleoon Data API

useRemoteVisitorData

A hook that returns asynchronous getRemoteVisitorData function which retrieves custom data from Kameleoon server and optionally adds it to storage.

import { useEffect, useCallback } from 'react';
import { useRemoteVisitorData } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { getRemoteVisitorData } = useRemoteVisitorData();

const getData = useCallback(async (): Promise<void> => {
// -- Get remote visitor data and add it to storage
const customDataList: KameleoonDataType[] = await getRemoteVisitorData(
'my_visitor_code',
);

// -- Get remote visitor data without adding to storage
const customDataList: KameleoonDataType[] = await getRemoteVisitorData(
'my_visitor_code',
false,
);
}, [getRemoteData]);

useEffect(() => {
getData();
}, [getData]);
}
Callback Parameters
NameTypeDescriptionDefault Value
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length-
shouldAddData (optional)booleanboolean flag identifying whether the retrieved custom data should be set to the storage like addData method doestrue
Callback Returns

KameleoonDataType[] - promise with list of custom data retrieved

Throws
TypeDescription
KameleoonException.RemoteDataCouldn't retrieve data from Kameleoon server

Define an action for real time configuration update

useConfigurationUpdate

A hook that returns onConfigurationUpdate function which fires a callback on client configuration update.

import { useEffect, useCallback } from 'react';
import { useInitialize, useConfigurationUpdate } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { onConfigurationUpdate } = useConfigurationUpdate();

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Define logic to be executed on client configuration update
onConfigurationUpdate(() => {
// -- My Logic
});
}, [initialize, onConfigurationUpdate]);

useEffect(() => {
init();
}, [init]);
}
note

This hook only works for server sent events of real time update

Callback Parameters
NameTypeDescription
callback (required)() => voidcallback function with no parameters that will be called upon configuration update
Throws
TypeDescription
KameleoonException.InitializationMethod was executed before initialize was done for kameleoonClient

Sending exposure events to external tools

Kameleoon offers built-in integrations with various analytics and CDP solutions, such as Mixpanel, GA4, Segment.... To ensure that you can track and analyze your server-side experiments, Kameleoon provides a method getEngineTrackingCode() that returns the JavasScript code to be inserted in your page to automatically send the exposure events to the analytics solution you are using. For more information about hybrid experimentation, please refer to this documentation.

note

To benefit from this feature, you will need to implement both the React SDK and our Kameleoon JavaScript tag. We recommend you implement the Kameleoon Asynchronous tag, which you can install before your closing <body> tag in your HTML page, as it will be only used for tracking purposes.

useEngineTrackingCode

A hook that returns getEngineTrackingCode() function which obtains Kameleoon tracking code for the current visitor. Tracking code is built based the experiments that were triggered during the last 5 seconds

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useTriggerExperiment,
useEngineTrackingCode,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { triggerExperiment } = useTriggerExperiment();
const { getEngineTrackingCode } = useEngineTrackingCode();

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Trigger an experiment
const experimentId = 100;
// -- E.g. result `variationId` is `200`
const variationId = triggerExperiment('visitor_code', experimentId);

// -- Get tracking code
const engineCode = getEngineTrackingCode('visitor_code');

// -- Result engine code will look like this
// `
// window.kameleoonQueue = window.kameleoonQueue || [];
// window.kameleoonQueue.push(['Experiments.assignVariation', 100, 200]);
// window.kameleoonQueue.push(['Experiments.trigger', 100, true]);
// `
}, [initialize, triggerExperiment, getEngineTrackingCode]);

useEffect(() => {
init();
}, [init]);
}
note

Result tracking code can be inserted directly into html <script> tag

For example:

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

script.textContent = engineTrackingCode;
document.body.appendChild(script);
</script>
</body>
</html>

Callback Parameters

NameTypeDescription
visitorCode (required)stringunique visitor identification string, can't exceed 255 characters length

Callback Returns

string containing engine tracking code


Data Types

Kameleoon Data types are helper classes used for storing data in storage in predefined forms. During the flushData execution all the data is collected and send along with tracking request.

Browser

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
Browser,
BrowserType,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Add new browser data to client
const browser = new Browser(BrowserType.Chrome);
addData(visitorCode, browser);
}, [initialize, addData, visitorCode]);

useEffect(() => {
init();
}, [init]);
}

Browser contains browser information.

Parameters

NameTypeDescription
browser (required)BrowserTypepredefined browser type (Chrome, InternetExplorer, Firefox, Safari, Opera, Other)

Conversion

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
Conversion,
ConversionParametersType,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Defined conversion parameters
const conversionParameters: ConversionParametersType = {
goalId: 123,
revenue: 10000,
negative: true,
};

// -- Add new conversion data to client
const conversion = new Conversion(conversionParameters);
addData(visitorCode, conversion);
}, [initialize, addData, visitorCode]);

useEffect(() => {
init();
}, [init]);
}

Conversion contains information about your conversion.

note

goalId can be found on Kameleoon Platform

Parameters

ConversionParametersType conversionParameters - an object with conversion parameters described below

NameTypeDescriptionDefault Value
goalId (required)numberan id of a goal to track-
browser (optional)numberan optional parameter for revenue0
negative (optional)booleanan optional parameter identifying whether the conversion should be removedfalse

CustomData

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
CustomData,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Defined conversion parameters
const dataItemOne = 'abc';
const dataItemTwo = JSON.stringify(100);
const dataItemThree = JSON.stringify({ a: 200, b: 300 });

const customDataIndex = 0;

// -- Create custom data using single parameter
const customData = new CustomData(customDataIndex, dataItemOne);

// -- Create custom data using variadic number of parameters
const customData = new CustomData(
customDataIndex,
dataItemOne,
dataItemTwo,
);

// -- Create custom data using an array of values
const dataList = [dataItemOne, dataItemTwo, dataItemThree];
const customData = new CustomData(customDataIndex, ...dataList);

// -- Add new custom data to client
addData(visitorCode, customData);
}, [initialize, addData, visitorCode]);

useEffect(() => {
init();
}, [init]);
}

CustomData is usually used together with custom data targeting condition on Kameleoon Platform to determine whether the visitor is targeted or not

note

The index or ID of the custom data can be found in your Kameleoon account. It is important to note that this index starts at 0, which means that the first custom data you create for a given site will be assigned 0 as its ID, not 1.

Parameters

NameTypeDescription
index (required)numberan index of custom data to be stored under in a state, an index of custom data can be specified in Advanced Tools section of Kameleoon Application
value (optional)string[]custom value to store under the specified id, value can be anything but has to be stringified to match the string type. Note value is variadic parameter and can be used as follows

Device

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
Device,
DeviceType,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Add new device data to client
const device = new Device(DeviceType.Desktop);
addData(visitorCode, device);
}, [initialize, addData, visitorCode]);

useEffect(() => {
init();
}, [init]);
}

Device contains information about your device.

Parameters

NameTypeDescription
deviceType (required)DeviceTypepossible variants for device type (PHONE, TABLET, DESKTOP)

PageView

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
PageView,
PageViewParametersType,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Define page view parameters
const pageViewParameters: PageViewParametersType = {
urlAddress: 'www.example.com',
title: 'my example',
referrers: [123, 456],
};

// -- Add new page view data to client
const pageView = new PageView(pageViewParameters);
addData(visitorCode, pageView);
}, [initialize, addData, visitorCode]);

useEffect(() => {
init();
}, [init]);
}

PageView contains information about your web page.

Parameters

PageViewParametersType pageViewParameters - an object with page view parameters described below

NameTypeDescription
urlAddress (required)stringurl address of the page to track
title (required)stringtitle of the web page
referrer (optional)number[]an optional parameter containing a list of referrers Indices, has no default value

UserAgent

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
UserAgent,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode('www.example.com');

const init = useCallback(async (): Promise<void> => {
await initialize();

// -- Add new user agent data to client
const userAgent = new UserAgent('my_unique_value');
addData(visitorCode, userAgent);
}, [initialize, addData, visitorCode]);

useEffect(() => {
init();
}, [init]);
}

UserAgent has a special meaning, if added to client it will be used provided value for filtering out bots during tracking requests

Parameters

NameTypeDescription
value (required)stringvalue used for comparison
caution

Server-side experiments are more vulnerable to bot traffic than client-side experiments. To address this, Kameleoon uses the IAB/ABC International Spiders and Bots List to identify known bots and spiders. We recommend that you pass the user agent to be filtered by Kameleoon when running server-side experiments for each visitor browsing your website, to avoid counting bots in your analytics.

If you use internal bots, we suggest that you pass the value curl/8.0 of the userAgent to exclude them from our analytics.

tip

If you run a Kameleoon hybrid experiment, your server-side experiments will be automatically protected against bot traffic. This is because Kameleoon collects the user-agent automatically on the front-end side. Therefore, you don't need to pass the user-agent or any other parameter to filter bots and spiders.

React Native Considerations

note

React Native on android platform doesn't support Real Time Update feature.

useNativeVisitorCode

note

React Native uses MMKV to store feature flag data so useBrowserVisitorCode hook won't be able to obtain visitor code safely, instead there is dedicated useNativeVisitorCode hook.

A hook that returns a callback function getNativeVisitorCode() which obtains visitor code from the storage, if no visitor code exists returns a new random visitor code (or the specified default value). This way it guarantees user identification consistency.

import { useNativeVisitorCode } from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { getNativeVisitorCode } = useNativeVisitorCode();

// -- Get visitor code
const visitorCode = getNativeVisitorCode();

// -- Pass default visitorCode, save and retrieve it
const visitorCode = getNativeVisitorCode('default_visitor_code');
}
Callback Parameters
NameTypeDescription
defaultVisitorCode (optional)stringvisitor code to be used instead of randomly generated visitor code in case there is no visitor code saved in storage
Callback Returns

string - result visitor code.

Error Handling

import { useEffect, useCallback } from 'react';
import {
useInitialize,
useBrowserVisitorCode,
useAddData,
CustomData,
KameleoonError,
KameleoonException,
} from '@kameleoon/react-sdk';

function MyComponent(): JSX.Element {
const { initialize } = useInitialize();
const { getBrowserVisitorCode } = useBrowserVisitorCode();
const { addData } = useAddData();

// -- Get visitor code
const visitorCode = getBrowserVisitorCode();

const init = useCallback(async (): Promise<void> => {
try {
await initialize();

const customData = new CustomData(0, 'my_data');
addData(visitorCode, customData);
} catch (error) {
// -- Type guard for inferring error type as native JavaScript `catch`
// only infers `unknown`
if (error instanceof KameleoonError) {
switch (error.type) {
case KameleoonException.VisitorCodeMaxLength:
// -- Handle an error
break;
case KameleoonException.StorageWrite:
// -- Handle an error
break;
case KameleoonException.Initialization:
// -- Handle an error
break;
default:
break;
}
}
}
}, [initialize, addData, visitorCode]);

useEffect(() => {
init();
}, [init]);
}

Almost every React SDK callback which is returned by hooks may throw an error at some point, these errors are not just caveats but rather deliberately predefined KameleoonErrors that extend native JavaScript Error class providing useful messages and special type field with a type KameleoonException.

KameleoonException is an enum containing all possible error variants.

To know exactly what variant of KameleoonException the callbacks may throw, you can check Throws section of the hooks description on this page or just hover over the callback in your IDE to see jsdocs description.

Overall handling the errors considered a good practice to make your application more stable and avoid technical issues.