NAV
  • React (Client-Side) SDK
  • React (Client-Side) 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 React Native application. Integrating our SDK into your web-application is easy, and its footprint (in terms of memory and network usage) is low.

    Requirements

    React SDK requires React 16.8.0+

    Installation

    npm install @kameleoon/react-sdk
    yarn add @kameleoon/react-sdk
    

    Installing the React SDK can be directly achieved through an npm or yarn module:

    Contents

    Follow the Usage section to configure your React App for work with feature flags. This section contains all the main steps for proper Kameleoon React SDK configuration as well as main tools for development.

    Optionally discover Additional Tools section containing useful information on a number of features, some useful utility hooks and higher-order components which will simplify the usage of React JS SDK.

    Usage

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

    1. Create and configure Kameleoon Client

    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.

    createClient

    import { createClient } from "@kameleoon/react-sdk";
    
    const client = createClient({
      siteCode: "0fpmcg34lg",
      visitorCode: "280295",
      options: {
        visitor_data_maximum_size: 1,
        actions_configuration_refresh_interval: 60,
        environment: 'staging'
      },
    });
    

    A KameleoonClient is created using createClient() callback function to run experiments and retrieve the status of feature flag and its variables.

    Arguments
    Returns
    Types

    2. Wrap application in Kameleoon Provider

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

    KameleoonProvider

    import { KameleoonProvider, createClient } from '@kameleoon/react-sdk';
    
    const client = createClient({
      siteCode: '0fpmcg34lg'
      visitorCode: '280295',
      options: {
        visitor_data_maximum_size: 1,
        actions_configuration_refresh_interval: 60,
        environment: 'staging'
      }
    });
    
    function AppWrapper(): JSX.Element {
      return (
        <KameleoonProvider client={client}>
          <App />
        </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
    Types

    3. Get access to feature flag inside React Components.

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

    There are two main ways in React SDK API that allow developer to grant control over the most important feature flag information useActivateFeature and useFeature hooks.

    Further is the detailed description on the usage of hooks and higher order component for gaining access to useActivateFeature and useFeature.

    useActivateFeature

    import { useEffect } from 'react';
    import { useActivateFeature, useVisitorCode, KameleoonException } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { hasFeature, error } = useActivateFeature();
      const { getVisitorCode } = useVisitorCode();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
        const featureKey = 'example-feature-key';
    
        if (error?.type === KameleoonException.NotTargeted) {
          // Handle error
        }
    
        if (error?.type === KameleoonException.FeatureConfigurationNotFound) {
          // Handle error
        }
    
        const feature = hasFeature(visitorCode, featureKey);
      }, []);
    
      ...
    }
    

    A hook that returns a callback function hasFeature() which validates if user has been associated with this feature along with an error object. If the callback fails, it returns value false, otherwise true.

    If feature flag is not activated, KameleoonException.FeatureConfigurationNotFound exception will be thrown.

    Callback arguments
    Callback returns
    Exceptions Thrown
    Error Handling

    An error object returned from the hook contains message: string, name: string and type: KameleoonException fields. A type key may be useful for comparing the returned error type against KameleoonException enum. If there were no errors error will be null.

    Types

    useFeature

    import { Button } from "@kameleoon/ui";
    import { useFeature, useVisitorCode, KameleoonException } from "@kameleoon/react-sdk";
    
    function MyComponent(): JSX.Element {
      const { getVisitorCode } = useVisitorCode();
      const { feature, errors } = useFeature({
        featureKey: "red-button",
        variableKeys: { production: 'red-button' },
        visitorCode: getVisitorCode("example.com"),
      });
    
      for (const error of errors) {
        if (error.type === KameleoonException.NotTargeted) {
          // Handle error
        }
    
        if (error.type === KameleoonException.FeatureConfigurationNotFound) {
          // Handle error
        }
      }
    
      const { isActive, variables } = feature;
    
      return <Button theme={isActive ? "red" : "green"} />;
    }
    

    A hook that returns feature object containing the information on both feature flag status and the list of variables along with an errors object, containing a list of kameleoon client errors. If not provided with visitorCode, will automatically generate one.

    Arguments
    Returns

    An object featureResult containing feature flag information and errors array of kameleoon client errors.

    In the examples, if the feature flag with the red-button key is enabled, theme of button will set to red.

    Exceptions Thrown
    Error Handling

    An errors array returned from the hook contains a list of KameleoonError. Each errors' type key may be useful for comparing the returned error type against KameleoonException enum. If there were no errors errors array will be empty.

    Types

    withActivateFeature

    import { withVisitorCode, withActivateFeature, compose, KameleoonException } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { getVisitorCode, hasFeature, activateFeatureError } = this.props;
        const visitorCode = getVisitorCode('example.com');
        const featureKey = 'example-feature-key';
    
        if (activateFeatureError?.type === KameleoonException.NotTargeted) {
          // Handle error
        }
    
        if (activateFeatureError?.type === KameleoonException.FeatureConfigurationNotFound) {
          // Handle error
        }
    
        const feature = hasFeature(visitorCode, featureKey);
      }
    
      ...
    }
    
    export default compose(withVisitorCode, withActivateFeature)(MyComponent);
    

    An alternative of useActivateFeature for React Class Components.

    Returns
    Error Handling

    Unlike useActivateFeature hook, which retrieves and error object, withActivateFeature HOC enhances props with named activateFeatureError error to avoid error naming intersection when using several HOCs within compose.

    withFeature

    import { Button } from "@kameleoon/ui";
    import { withFeature, KameleoonException } from "@kameleoon/react-sdk";
    
    class MyComponent extends React.Component {
      state = { 
        isActive: false,
        variables: [],
      }
    
      componentDidMount() {
        const { feature, errors } = this.props;
    
        for (const error of errors) {
          if (error.type === KameleoonException.NotTargeted) {
            // Handle error
          }
    
          if (error.type === KameleoonException.FeatureConfigurationNotFound) {
            // Handle error
          }
        }
    
        const { isActive, variables } = feature;
    
        this.setState({ isActive, variables });
      }
    
      render() {
        return <Button theme={isActive ? "red" : "green"} />;
      }
    }
    
    export default withFeature({
      featureKey: "red-button",
      variableKeys: { production: 'red-button' },
      visitorCode: "280295",
    })(MyComponent);
    

    An alternative for useFeature for React Class Components.

    Arguments
    Returns

    In the examples, if the feature flag with the red-button key is enabled, theme of button will set to red.

    Feature

    import { Button } from '@kameleoon/ui';
    import { Feature } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      state = { 
        isActive: false,
        variables: [],
      }
    
      componentDidMount() {
        const { feature, errors } = this.props;
    
        for (const error of errors) {
          if (error.type === KameleoonException.NotTargeted) {
            // Handle error
          }
    
          if (error.type === KameleoonException.FeatureConfigurationNotFound) {
            // Handle error
          }
        }
    
        const { isActive, variables } = feature;
    
        this.setState({ isActive, variables });
      }
    
      render() {
        return <Button theme={this.isActive ? 'red' : 'green'} />;
      }
    }
    
    class MyComponentWrapper extends React.Component { 
      render() {
        return(
          <Feature 
            featureKey="red-button" 
            variableKeys={{production: "red-button"}} 
            visitorCode="280295"
          >
            (({ feature, errors }) => (
              <MyComponent feature={feature} errors={errors} />
            ))
          </Feature>;
        )
      }
    }
    

    An alternative for useFeature and withFeature which utilizes React Render Props pattern.

    Props
    Returns

    A wrapped component with the following props:

    In the examples, if the feature flag with the red-button key is enabled, theme of button will set to red.

    4. (Optional) Use Kameleoon Client directly.

    React JS SDK allows the developer to communicate with Kameleoon JS/TS sdk directly ignoring existing hooks and HOCs methods.

    useKameleoon

    import { useKameleoon } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { client } = useKameleoon();
    
      ...
    }
    

    Gives direct access to Kameleoon JS/TS client.

    Returns

    withKameleoon

    import { withKameleoon } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { client } = this.props;
      }
    
      ...
    }
    
    export default withKameleoon(MyComponent);
    

    An alternative to useKameleoon, gives direct access to Kameleoon JS/TS client.

    Returns

    Additional Tools

    Variation Associated Data

    A callback function getVariationAssociatedData() retrieved via useVariationAssociatedData or withVariationAssociatedData obtains JSON data associated with a variation. The JSON data usually represents some metadata of the variation, and can be configured on our web application interface or via our Automation API.

    useVariationAssociatedData

    import { useEffect } from 'react';
    import { useVariationAssociatedData, KameleoonException } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { getVariationAssociatedData } = useVariationAssociatedData();
    
      useEffect(() => {
        const variationId = 280295;
    
        if (error?.type === KameleoonException.VariationConfigurationNotFound) {
          // Handle error
        }
    
        const data = getVariationAssociatedData(variationId);
      }, []);
    
      ...
    }
    

    Callback function getVariationAssociatedData takes the variationId as a parameter and will return the data as a JavaScript object along with an error object. It will throw an exception (KameleoonException.VariationConfigurationNotFound) if the variationId is wrong or corresponds to an experiment that is not yet online.

    Callback Arguments
    Callback Returns
    Exceptions Thrown
    Error Handling

    An error object returned from the hook contains message: string, name: string and type: KameleoonException fields. A type key may be useful for comparing the returned error type against KameleoonException enum. If there were no errors error will be null.

    Types

    withVariationAssociatedData

    import { withVariationAssociatedData, KameleoonException } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { getVariationAssociatedData, variationAssociatedDataError } = this.props;
        const variationId = 280295;
    
        if (variationAssociatedDataError?.type === KameleoonException.VariationConfigurationNotFound) {
          // Handle error
        }
    
        const data = getVariationAssociatedData(variationId);
      }
    
      ...
    }
    
    export default withVariationAssociatedData(MyComponent);
    

    An alternative for useVariationAssociatedData.

    Arguments
    Returns
    Error Handling

    Unlike useVariationAssociatedData hook, which retrieves and error object, withVariationAssociatedData HOC enhances props with named variationAssociatedDataError error to avoid error naming intersection when using several HOCs within compose.

    Local Storage Key

    import { KAMELEOON_SDK_LOCAL_STORAGE_KEY } from "@kameleoon/react-sdk";
    

    KAMELEOON_SDK_LOCAL_STORAGE_KEY - is a constant which used as a key in LocalStorage to store a kameleoonTargetingData and kameleoonConfiguration.

    Visitor Code

    A callback function getVisitorCode() retrieved by useVisitorCode or withVisitorCode obtains the Kameleoon visitorCode for the current visitor. This is especially important when using Kameleoon in a mixed front-end and back-end environment, where user identification consistency must be guaranteed. The implementation logic:

    1. First we check if a kameleoonVisitorCode cookie can be found. If so, we will use this as the visitor identifier.

    2. If no cookie was found, we either randomly generate a new identifier, or use the defaultVisitorCode 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 JavaScript kameleoonVisitorCode cookie is set with the value. Then this identifier value is finally returned by the method.

    For more information, refer to this article.

    useVisitorCode

    import { useEffect } from 'react';
    import { uuidv4 } from 'uuid';
    import { useVisitorCode } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { getVisitorCode } = useVisitorCode();
    
      useEffect(() => {
        // Without defaultVisitorCode argument
        const visitorCode = getVisitorCode('example.com');
    
        // With defaultVisitorCode argument
        const visitorCode = getVisitorCode('example.com', uuidv4());
      }, []);
    
      ...
    }
    

    useVisitorCode returns a callback function getVisitorCode() used to obtain visitor code.

    Callback Arguments
    Callback Returns

    withVisitorCode

    import { uuidv4 } from 'uuid';
    import { withVisitorCode } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { getVisitorCode } = this.props;
    
        // Without defaultVisitorCode argument
        const visitorCode = getVisitorCode('example.com');
    
        // With defaultVisitorCode argument
        const visitorCode = getVisitorCode('example.com', uuidv4());
      }
    
      ...
    }
    
    export default withVisitorCode(MyComponent);
    

    An alternative for useVisitorCode hook.

    Arguments
    Returns

    Trigger an Experiment

    A callback function getVariationId() retrieved via useTriggerExperiment or useTriggerExperiment takes visitorCode and experimentId as mandatory arguments to register a variation for a given user.

    If such a user has never been associated with any variation, the SDK returns a randomly selected variation. If a user with a given visitorCode is already registered with a variation, it will detect the previously registered variation and return the variationId.

    You have to make sure that proper error handling is set up in your code as shown in the example to the right to catch potential exceptions.

    Please Note:

    useTriggerExperiment

    import { useEffect } from 'react';
    import { useTriggerExperiment, useVisitorCode, KameleoonException } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { getVariationId, error } = useTriggerExperiment();
      const { getVisitorCode } = useVisitorCode();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
        const experimentId = 12341;
    
        if (error?.type === KameleoonException.ExperimentConfigurationNotFound) {
          // Handle exception
        }
    
        if (error?.type === KameleoonException.NotTargeted) {
          // Handle exception
        }
    
        if (error?.type === KameleoonException.NotActivated) {
          // Handle exception
        }
    
        const variationId = getVariationId(visitorCode, experimentId);
      }, []);
    
      ...
    }
    

    useTriggerExperiment hook returns getVisitorCode() function used for triggering an experiment along with an error object.

    Callback Arguments
    Callback Returns
    Exceptions Thrown
    Error Handling

    An error object returned from the hook contains message: string, name: string and type: KameleoonException fields. A type key may be useful for comparing the returned error type against KameleoonException enum. If there were no errors error will be null.

    Types

    withTriggerExperiment

    import { withVisitorCode, withTriggerExperiment, compose, KameleoonException } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { getVisitorCode, getVariationId, triggerExperimentError } = this.props;
        const visitorCode = getVisitorCode('example.com');
        const experimentId = 230243;
    
        if (triggerExperimentError?.type === KameleoonException.ExperimentConfigurationNotFound) {
          // Handle exception
        }
    
        if (triggerExperimentError?.type === KameleoonException.NotTargeted) {
          // Handle exception
        }
    
        if (triggerExperimentError?.type === KameleoonException.NotActivated) {
          // Handle exception
        }
    
        const variationId = getVariationId(visitorCode, experimentId);
      }
    
      ...
    }
    
    export default compose(withVisitorCode, withTriggerExperiment)(MyComponent);
    

    An alternative for useTriggerExperiment hook.

    Arguments
    Returns
    Error Handling

    Unlike useTriggerExperiment hook, which retrieves and error object, withTriggerExperiment HOC enhances props with named triggerExperimentError error to avoid error naming intersection when using several HOCs within compose.

    Feature Variables

    A callback function getFeatureVariable() retrieved by useFeatureVariable or withFeatureVariable is used to obtain a feature variable.

    This callback function takes two input parameters: featureKey and variableKey. It will return the data with the expected type, as defined on the web interface. It will throw an exception (KameleoonException.FeatureConfigurationNotFound) if the requested feature has not been found in the internal configuration of the SDK.

    useFeatureVariable

    import { useEffect } from 'react';
    import { useFeatureVariable, KameleoonException } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { getFeatureVariable, error } = useFeatureVariable();
    
      useEffect(() => {
        const featureKey = 'example-feature-key';
        const variableKey = 'example-variable-key';
    
        if (error?.type === KameleoonException.FeatureConfigurationNotFound) {
          // Handle error
        }
    
        const featureVariable = getFeatureVariable(featureKey, variableKey);
      }, []);
    
      ...
    }
    

    useFeatureVariable returns a callback function getFeatureVariable() used to obtain feature variables along with an error object.

    Callback Arguments
    Callback Returns
    Exceptions Thrown
    Error Handling

    An error object returned from the hook contains message: string, name: string and type: KameleoonException fields. A type key may be useful for comparing the returned error type against KameleoonException enum. If there were no errors error will be null.

    Types

    withFeatureVariable

    import { withFeatureVariable, KameleoonException } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { getFeatureVariable, featureVariableError } = this.props;
        const featureKey = 'example-feature-key';
        const variableKey = 'example-variable-key';
    
        if (featureVariableError?.type === KameleoonException.FeatureConfigurationNotFound) {
          // Handle error
        }
    
        const featureVariable = getFeatureVariable(featureKey, variableKey);
      }
    
      ...
    }
    
    export default withFeatureVariable(MyComponent);
    

    An alternative for useFeatureVariable hook.

    Arguments
    Returns
    Error Handling

    Unlike useFeatureVariable hook, which retrieves and error object, withFeatureVariable HOC enhances props with named featureVariableError error to avoid error naming intersection when using several HOCs within compose.

    Track Conversion

    A callback function trackConversion() retrieved via useTrackingConversion or withTrackingConversion is used to track conversion. This callback function requires visitorCode and goalId to track conversion on this particular goal. In addition, trackConversion() accepts third optional argument revenue to track revenue. The visitorCode is usually identical to the one that was used when triggering the experiment.

    trackConversion() doesn't return any value. And it is non-blocking as the server call is made asynchronously.

    useTrackingConversion

    import { useEffect } from 'react';
    import { useTrackingConversion, useVisitorCode } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { getVisitorCode } = useVisitorCode();
      const { trackConversion } = useTrackingConversion();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com')
        const goalId = 280295;
    
        trackConversion(visitorCode, goalId);
      }, []);
    
      ...
    }
    

    useTrackingConversion returns a callback function trackConversion() used for tracking conversion.

    Callback Arguments
    Returns

    withTrackingConversion

    import { withVisitorCode, withTrackingConversion, compose } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { getVisitorCode, trackConversion } = this.props;
        const visitorCode = getVisitorCode('example.com');
        const goalId = 230234;
    
        trackConversion(visitorCode, goalId);
      }
    
      ...
    }
    
    export default compose(withVisitorCode, withTrackingConversion)(MyComponent);
    

    An alternative for useTrackingConversion hook.

    Arguments
    Returns

    Retrieve Data from Remote Source

    An callback function retrieveDataFromRemoteSource() retrieved via useRetrieveDataFromRemoteSource or withRetrieveDataFromRemoteSource can be used to retrieve data using specific key and siteCode from Kameleoon provider. The Data is stored on a remote Kameleoon server. Usually data will be stored on our remote servers via the use of our Data API. This method, along with the availability of our highly scalable servers for this purpose, provides a convenient way to quickly store massive amounts of data that can be later retrieved for each of your visitors / users.

    useRetrieveDataFromRemoteSource

    import { useEffect, useCallback } from 'react';
    import { useRetrieveDataFromRemoteSource, RemoteSourceDataType } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { retrieveDataFromRemoteSource } = useRetrieveDataFromRemoteSource();
    
      const processRetrievedData = useCallback(async () => {
        const data: RemoteSourceDataType = await retrieveDataFromRemoteSource('example-key');
        // Your code
      }, [retrieveDataFromRemoteSource]);
    
      useEffect(() => {
        processRetrievedData();
      }, [processRetrievedData]);
    
      ...
    }
    

    useRetrieveDataFromRemoteSource returns retrieveDataFromRemoteSource() callback used for obtaining remote data.

    Callback Arguments
    Callback Returns
    Returns
    Types

    withRetrieveDataFromRemoteSource

    import { withRetrieveDataFromRemoteSource, RemoteSourceDataType } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      async componentDidMount() {
        const { retrieveDataFromRemoteSource } = this.props;
        const data: RemoteSourceDataType = await getVariationAssociatedData('example-key');
        // Your code
      }
    
      ...
    }
    
    export default withRetrieveDataFromRemoteSource(MyComponent);
    

    An alternative for useRetrieveDataFromRemoteSource hook.

    Arguments
    Returns
    Types

    Add User Data

    A callback function addData() retrieved via useAddData or withAddData is used to add various data to associate with the current user. This callback function requires visitorCode as a first parameter and then accepts array of various Data Types allowed in Kameleoon.

    useAddData

    import { useEffect } from 'react';
    import { Button } from '@kameleoon/ui';
    import {
      useAddData,
      useBrowser,
      useCustomData,
      useVisitorCode,
      Browser
    } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { getVisitorCode } = useVisitorCode();
      const { addData } = useAddData();
      const { addBrowser } = useBrowser();
      const { addCustomData } = useCustomData();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
    
        // Single data type passed
        addData(visitorCode, [addBrowser(Browser.Chrome)]);
    
        // Several data types passed
        addData(visitorCode, [addBrowser(Browser.Chrome), addCustomData(1, 'some custom value')]);
      }, []);
    
      ...
    }
    

    useAddData hook returns a callback function addData used to add client associated data. useAddData, useBrowser and useCustomData shown in code example are used to correctly structure the data.

    Callback Arguments

    withAddData

    import {
      withAddData,
      withBrowser,
      withCustomData,
      withVisitorCode,
      Browser,
      compose,
    } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { addData, addBrowser, addCustomData, getVisitorCode } = this.props;
        const visitorCode = getVisitorCode('example.com');
    
        // Single data type passed
        addData(visitorCode, [addBrowser(Browser.Chrome)]);
    
        // Several data types passed
        addData(visitorCode, [
          addBrowser(Browser.Chrome),
          addCustomData(1, 'some custom value'),
        ]);
      }
    
      ...
    }
    
    export default compose(
      withAddData,
      withBrowser,
      withCustomData,
      withVisitorCode,
    )(MyComponent);
    

    An alternative for useAddData hook.

    Arguments
    Returns

    Run When Ready

    In certain scenarios when working with Kameleoon API it's important to make sure that the client was initialized properly within the certain timeout. It's especially important while using triggerExperiment() or trackConversion(). For these cases it's possible to use runWhenReady() function, retrieved by useRunWhenReady hook or withRunWhenReady high-order component.

    useRunWhenReady

    import { useEffect, useCallback, useState } from 'react';
    import { useRunWhenReady, useTriggerExperiment } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { runWhenReady } = useRunWhenReady();
      const { getVariationId } = useTriggerExperiment();
    
      const [variationId, setVariationId] = useState<number>(0);
    
      const getVariationSuccessCallback = useCallback(() => {
        const id = getVariationId('user_id', 12345);
        setVariationId(id);
      }, [getVariationId, isRenderProps]);
    
      const getVariationErrorCallback = useCallback(() => {
        throw new Error(
          "Couldn't get server configuration from HTTP request in a specified time",
        );
      }, []);
    
      useEffect(() => {
        runWhenReady(
          getVariationSuccessCallback,
          getVariationErrorCallback,
          1000,
        );
      }, [runWhenReady, getVariationSuccessCallback, getVariationErrorCallback]);
    
      ...
    }
    

    The runWhenReady() function makes sure that Kameleoon Client will be initialized properly using HTTP call withing the specified timeout.

    Callback Arguments

    withRunWhenReady

    import { useEffect, useCallback, useState } from 'react';
    import { withRunWhenReady, withTriggerExperiment } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      variationSuccessCallback(): void {
        const id = this.props.getVariationId('user_id', 12345);
        setVariationId(id);
      }
    
      variationErrorCallback(): void {
        const id = this.props.getVariationId('user_id', 12345);
        setVariationId(id);
      }
    
      componentDidMount() {
        this.props.runWhenReady(this.variationSuccessCallback, this.variationErrorCallback, 1000);
      }
    
      ...
    }
    
    export default compose(
      withRunWhenReady,
      withTriggerExperiment,
    )(MyComponent);
    

    An alternative for useRunWhenReady hook.

    Arguments
    Returns

    Data Flush

    Data associated with the current user via addData() is not immediately sent to the server. It is stored and accumulated until it is sent automatically by the triggerExperiment() or trackConversion(), or manually by the flush() callback function which is retrieve via useFlush or withFlush. This allows the developer to control exactly when the data is flushed to servers. For instance, if you call the addData() a dozen times, it would be a waste of resources to send data to the server after each addData() invocation. Just call flush() once at the end.

    The flush() callback function is non-blocking as the server call is made asynchronously.

    useFlush

    import { useEffect } from 'react';
    import { Button } from '@kameleoon/ui';
    import {
      useAddData,
      useBrowser,
      useVisitorCode,
      useFlush,
      Browser
    } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { getVisitorCode } = useVisitorCode();
      const { addData } = useAddData();
      const { addBrowser } = useBrowser();
      const { flush } = useFlush();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addBrowser(Browser.Chrome)]);
        flush(visitorCode);
      }, []);
    
      ...
    }
    

    useFlush return a callback function flush(). useBrowser used in the example is used to structure the data correctly.

    Callback Arguments

    withFlush

    import {
      withVisitorCode,
      withAddData,
      withBrowser,
      withFlush,
      Browser,
      compose,
    } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { addData, addBrowser, flush, getVisitorCode } = this.props;
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addBrowser(Browser.Chrome)]);
        flush(visitorCode);
      }
    
      ...
    }
    
    export default compose(
      withAddData,
      withBrowser,
      withFlush,
      withVisitorCode,
    )(MyComponent);
    

    An alternative for useFlush hook.

    Arguments
    Returns

    Data Structure

    The following set of hooks and higher-order components are serving the purpose of structuring the data passed to addData() function correctly.

    useBrowser

    import { useEffect } from 'react';
    import { useAddData, useBrowser, useVisitorCode, Browser } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { addData } = useAddData();
      const { getVisitorCode } = useVisitorCode();
      const { addBrowser } = useBrowser();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addBrowser(Browser.Chrome)]);
      }, []);
    
      ...
    }
    

    useBrowser return a callback function addBrowser() which add chosen browser to user associated data.

    Callback Arguments
    Callback Returns
    Types

    withBrowser

    import {
      withVisitorCode,
      withAddData,
      withBrowser,
      Browser,
      compose,
    } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { addData, addBrowser, getVisitorCode } = this.props;
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addBrowser(Browser.Chrome)]);
      }
    
      ...
    }
    
    export default compose(
      withAddData,
      withBrowser,
      withVisitorCode,
    )(MyComponent);
    

    An alternative for useBrowser hook.

    Arguments
    Returns

    usePageView

    import { useEffect } from 'react';
    import { useAddData, usePageView, useVisitorCode } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { addData } = useAddData();
      const { getVisitorCode } = useVisitorCode();
      const { addPageView } = usePageView();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addPageView('example.com', 'title', 3)]);
      }, []);
    
      ...
    }
    

    usePageView hook returns a callback function addPageView() used to structure page view data.

    Callback Arguments
    Callback Returns
    Types

    withPageView

    import {
      withVisitorCode,
      withAddData,
      withPageView,
      compose,
    } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { addData, addPageView, getVisitorCode } = this.props;
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addPageView('example.com', 'title', 3)]);
      }
    
      ...
    }
    
    export default compose(
      withAddData,
      withPageView,
      withVisitorCode,
    )(MyComponent);
    

    An alternative for usePageView hook.

    Arguments
    Returns

    useConversion

    import { useEffect } from 'react';
    import { useAddData, useConversion, useVisitorCode } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { addData } = useAddData();
      const { getVisitorCode } = useVisitorCode();
      const { addConversion } = useConversion();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addConversion(32, 10, false)]);
      }, []);
    
      ...
    }
    

    useConversion hook returns a callback function addConversion() used to structure conversion data.

    Callback Arguments
    Callback Returns
    Types

    withConversion

    import {
      withVisitorCode,
      withAddData,
      withConversion,
      compose,
    } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { addData, addConversion, getVisitorCode } = this.props;
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addConversion(32, 10, false)]);
      }
    
      ...
    }
    
    export default compose(
      withAddData,
      withConversion,
      withVisitorCode,
    )(MyComponent);
    

    An alternative for useConversion hook.

    Arguments
    Returns

    useInterest

    import { useEffect } from 'react';
    import { useAddData, useInterest, useVisitorCode } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { addData } = useAddData();
      const { getVisitorCode } = useVisitorCode();
      const { addInterest } = useInterest();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addInterest(0)]);
      }, []);
    
      ...
    }
    

    useInterest hook returns a callback function addInterest() used to structure interest data.

    Callback Arguments
    Callback Returns
    Types

    withInterest

    import {
      withVisitorCode,
      withAddData,
      withInterest,
      compose,
    } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { addData, addInterest, getVisitorCode } = this.props;
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addInterest(0)]);
      }
    
      ...
    }
    
    export default compose(
      withAddData,
      withInterest,
      withVisitorCode,
    )(MyComponent);
    

    An alternative for useInterest hook.

    Arguments
    Returns

    useCustomData

    import { useEffect } from 'react';
    import { useAddData, useCustomData, useVisitorCode } from '@kameleoon/react-sdk';
    
    function MyComponent(): JSX.Element {
      const { addData } = useAddData();
      const { getVisitorCode } = useVisitorCode();
      const { addCustomData } = useCustomData();
    
      useEffect(() => {
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addCustomData(1, 'some custom value')]);
      }, []);
    
      ...
    }
    

    useCustomData hook returns a callback function addCustomData used to structure custom data.

    Arguments
    Returns
    Types

    withCustomData

    import {
      withVisitorCode,
      withAddData,
      withCustomData,
      compose,
    } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { addData, addCustomData, getVisitorCode } = this.props;
        const visitorCode = getVisitorCode('example.com');
    
        addData(visitorCode, [addCustomData(1, 'some custom value')]);
      }
    
      ...
    }
    
    export default compose(
      withAddData,
      withCustomData,
      withVisitorCode,
    )(MyComponent);
    

    An alternative for useAddData hook.

    Arguments
    Returns

    Compose

    import { withVisitorCode, withTriggerExperiment, compose } from '@kameleoon/react-sdk';
    
    class MyComponent extends React.Component {
      componentDidMount() {
        const { getVisitorCode, getVariationId } = this.props;
        const visitorCode = getVisitorCode('example.com');
        const experimentId = 230243;
    
        const variationId = getVariationId(visitorCode, experimentId);
      }
    
      ...
    }
    
    export default compose(withVisitorCode, withTriggerExperiment)(MyComponent);
    

    compose() is a helper higher-order component used for easier composition.

    Arguments
    Returns