> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kameleoon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK React

> Intégrez le SDK React de Kameleoon pour exécuter des expériences et activer des feature flags dans des applications React en utilisant des hooks et des composants.

Avec le SDK React de Kameleoon, vous pouvez exécuter des expériences de fonctionnalités et activer des feature flags dans vos applications web et mobiles front-end. L'intégration de notre SDK dans votre application est simple, et son empreinte (utilisation de la mémoire et du réseau) est faible.

**Premiers pas** : pour obtenir de l'aide pour démarrer, consultez le [guide du développeur](#guide-du-développeur)

**Changelog** : les détails sur la dernière version du SDK React sont disponibles dans le [changelog](https://github.com/Kameleoon/client-react/blob/main/CHANGELOG.md).

**Méthodes du SDK** : pour la documentation de référence complète du SDK React, consultez la section [référence](#référence).

**Prérequis** : le SDK React nécessite `React 16.8.0+`

## Guide du développeur

Suivez cette section pour intégrer le SDK dans votre application et en apprendre davantage sur son utilisation.

### Premiers pas

Cette section vous guide à travers l'installation et la configuration du SDK pour la première fois.

#### Installation

L'outil d'installation du SDK Kameleoon est la méthode recommandée pour installer le SDK. Cet **installateur de SDK** vous aide à installer le SDK de votre choix, à générer un exemple de code de base et à configurer les [dépendances externes](#external-dependencies) si nécessaire.

Pour démarrer l'outil d'installation du SDK, installez-le et exécutez-le globalement :

```bash theme={null}
npm install --global @kameleoon/sdk-installer
kameleoon-sdk
```

Ou exécutez-le directement avec `npx`:

```bash theme={null}
npx @kameleoon/sdk-installer
```

#### Créer le client Kameleoon

Pour commencer, créez un point d'entrée pour le SDK React en créant le client Kameleoon au niveau supérieur de votre application. Créez une instance de `KameleoonClient` en utilisant la fonction `createClient()`, importée du package `kameleoon`.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import {
      createClient,
      Environment,
      SDKConfigurationType,
    } from '@kameleoon/react-sdk';

    // -- Optional configuration
    const configuration: Partial<SDKConfigurationType> = {
      updateInterval: 60,
      environment: Environment.Production,
      cookieDomain: '.example.com',
    };

    const client = createClient({ siteCode: 'my_site_code', configuration });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { createClient, Environment } from '@kameleoon/react-sdk';

    // -- Optional configuration
    const configuration = {
      updateInterval: 60,
      environment: Environment.Production,
      cookieDomain: '.example.com',
    };

    const client = createClient({ siteCode: 'my_site_code', configuration });
    ```
  </Tab>
</Tabs>

#### Encapsuler l'application dans le Kameleoon Provider

La deuxième étape consiste à connecter le client Kameleoon précédemment créé a `KameleoonProvider` en passant le client configuré a `KameleoonProvider`:

<Tabs defaultTabIndex={0}>
  <Tab title="TS">
    ```tsx theme={null}
    import {
      createClient,
      Environment,
      KameleoonProvider,
    } from '@kameleoon/react-sdk';

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

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

  <Tab title="JS">
    ```jsx theme={null}
    import {
      createClient,
      Environment,
      KameleoonProvider,
    } from '@kameleoon/react-sdk';

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

    function AppWrapper() {
      return (
        <KameleoonProvider client={client}>
          <App />
        </KameleoonProvider>
      );
    }
    ```
  </Tab>

  <Tab title="NextJS (TS)">
    <Warning>
      Si vous utilisez **Next.js** pour le rendu côté serveur (SSR), vous **devez** utiliser `KameleoonProviderSSR` ou `KameleoonProvider` avec `stubMode=true`.
      Cela empêche l'initialisation du client SDK sur le serveur et garantit que le SDK React s'exécute exclusivement côté client.
    </Warning>

    ```tsx theme={null}
    import {
      createClient,
      Environment,
      KameleoonProviderSSR,
    } from '@kameleoon/react-sdk';

    function AppWrapper(): JSX.Element {
      return (
        <KameleoonProviderSSR sdkParameters={{
          siteCode: 'my_site_code',
          configuration: {
            updateInterval: 60,
            environment: Environment.Production,
          }
        }}>
          <App />
        </KameleoonProviderSSR>
      );
    }
    ```
  </Tab>

  <Tab title="NextJS (JS)">
    <Warning>
      Si vous utilisez **Next.js** pour le rendu côté serveur (SSR), vous **devez** utiliser `KameleoonProviderSSR` ou `KameleoonProvider` avec `stubMode=true`.
      Cela empêche l'initialisation du client SDK sur le serveur et garantit que le SDK React s'exécute exclusivement côté client.
    </Warning>

    ```jsx theme={null}
    import {
      createClient,
      Environment,
      KameleoonProviderSSR,
    } from '@kameleoon/react-sdk';

    function AppWrapper() {
      return (
        <KameleoonProviderSSR sdkParameters={{
          siteCode: 'my_site_code',
          configuration: {
            updateInterval: 60,
            environment: Environment.Production,
          }
        }}>
          <App />
        </KameleoonProviderSSR>
      );
    }
    ```
  </Tab>

  <Tab title="NextJS with externals(TS)">
    <Warning>
      Si vous utilisez **Next.js** pour le rendu côté serveur (SSR), vous **devez** utiliser `KameleoonProviderSSR` ou `KameleoonProvider` avec `stubMode=true`.
      Cela empêche l'initialisation du client SDK sur le serveur et garantit que le SDK React s'exécute exclusivement côté client.
    </Warning>

    ```tsx theme={null}
    import {
      createClient,
      Environment,
      KameleoonProvider,
    } from '@kameleoon/react-sdk';

    // Checks if the code is running sur le serveur (Node.js) and not in the browser.
    // This can be replaced with any other mechanism you use to detect server-side execution.
    const isServer = typeof window === 'undefined';

    const client = createClient({
      siteCode: 'my_site_code',
      configuration: {
        updateInterval: 60,
        environment: Environment.Production,
      },
      externals: {
        // Add your external dependencies here, e.g. storage, eventSource, visitorCodeManager, etc.
      },
      stubMode: isServer,
    });

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

  <Tab title="NextJS with externals(JS)">
    <Warning>
      Si vous utilisez **Next.js** pour le rendu côté serveur (SSR), vous **devez** utiliser `KameleoonProviderSSR` ou `KameleoonProvider` avec `stubMode=true`.
      Cela empêche l'initialisation du client SDK sur le serveur et garantit que le SDK React s'exécute exclusivement côté client.
    </Warning>

    ```jsx theme={null}
    import {
      createClient,
      Environment,
      KameleoonProvider,
    } from '@kameleoon/react-sdk';

    // Checks if the code is running sur le serveur (Node.js) and not in the browser.
    // This can be replaced with any other mechanism you use to detect server-side execution.
    const isServer = typeof window === 'undefined';

    const client = createClient({
      siteCode: 'my_site_code',
      configuration: {
        updateInterval: 60,
        environment: Environment.Production,
      },
      externals: {
        // Add your external dependencies here, e.g. storage, eventSource, visitorCodeManager, etc.
      },
      stubMode: isServer,
    });

    function AppWrapper() {
      return (
        <KameleoonProvider client={client}>
          <App />
        </KameleoonProvider>
      );
    }
    ```
  </Tab>
</Tabs>

##### KameleoonProvider

Utilisez ce provider au niveau racine en encapsulant votre application pour obtenir un accès à `KameleoonClient`. This ensures your app ne fait pas flicker due to flag changes at startup time.

###### Props

| Name                  | Type              | Description                                            |
| --------------------- | ----------------- | ------------------------------------------------------ |
| children (*required*) | `ReactNode`       | éléments enfants du provider                           |
| client (*required*)   | `KameleoonClient` | `KameleoonClient` instance created by `createClient()` |

##### KameleoonProviderSSR

Utilisez ce provider au niveau racine en encapsulant votre application pour obtenir un accès à `KameleoonClient`.
`KameleoonProviderSSR` diffère de `KameleoonProvider` car il crée une `KameleoonClient` instance à l'intérieur du contexte lors de la première requête du client. This empêche le risque de créer le client côté serveur. C'est recommandé pour une utilisation dans les systèmes basés sur le SSR, tel que Next.js with SSR.

###### Props

| Name                       | Type            | Description                                                             |
| -------------------------- | --------------- | ----------------------------------------------------------------------- |
| children (*required*)      | `ReactNode`     | éléments enfants du provider                                            |
| sdkParameters (*required*) | `SDKParameters` | `SDKParameters` paramètres pour créer une instance de `KameleoonClient` |

#### Await for le client initialization

`KameleoonClient` initialization is done asynchronously afin de assurez-vous that Kameleoon API call was successful for that hook `useInitialize` is used. Vous pouvez utiliser `async/await`, `Promise.then()` or any other method to handle asynchronous client initialization.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    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]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

#### Activating a feature flag

##### Assigning a unique ID to a utilisateur

To assign a unique ID to a utilisateur, vous pouvez utiliser the [`getVisitorCode()`](#getvisitorcode) method. If a **visiteur code** n'existe pas (depuis le cookie des en-têtes de la requête), la méthode generates a random unique ID or uses a `defaultVisitorCode` that you would have generated. The ID est est ensuite placé in le cookie des en-têtes de la réponse.

Si vous êtes using Kameleoon in [Hybrid mode](/developer-docs/feature-experimentation/get-started/hybrid-experimentation), calling the `getVisitorCode()` method ensures that the unique ID (**visiteur code**) is shared between l'application fichier `engine.js` (previously named, `kameleoon.js`) and le SDK.

##### Retrieving a flag configuration

To implement a feature flag in your code, vous devez first create the feature flag in your Kameleoon account.

To determine the status or variation of a feature flag for a specific utilisateur, vous devriez utilisez la [`getVariation()`](#getvariation) or [`isFeatureFlagActive()`](#isfeatureflagactive) method to retrieve the configuration basé sur the `featureKey`.

The `getVariation()` method handles both simple feature flags with ON/OFF states and more complex flags with multiple variations. The method retrieves the appropriate variation for l'utilisateur by checking the feature rules, assigning the variation, and returning it basé sur the `featureKey` and `visitorCode`.

The `isFeatureFlagActive()` method peut être used si vous voulez retrieve the configuration of a simple feature flag that has only an ON or OFF state, as opposed to more complex feature flags with multiple variations or ciblage options.

If your feature flag has associated variables (tel que specific behaviors tied to each variation) `getVariation()` also enables you to access the [`Variation`](#variation) object, which provides détails about the assigned variation and its associated expérience. Cette méthode checks whether l'utilisateur is targeted, finds le visiteur's assigned variation, and saves it to storage. When `track=true`, le SDK will send the exposure événement to the specified expérience on the next suivi request, qui est automatically triggered basé sur le SDK's [`tracking_interval_millisecond`](#configuration-parameters). Par défaut, this interval is set to 1000 milliseconds (1 second).

The `getVariation()` method allows you to control whether suivi is done. If `track=false`, no exposure événements sera sent by le SDK. This is useful if vous préférez ne pas suivre données through le SDK and instead rely on client-side suivi managed by the Kameleoon engine, par exemple. De plus, setting `track=false` is helpful when en utilisant la fonction `getVariations()` method, where you might only need the variations for all flags without triggering any suivi événements. Si vous voulez en savoir plus sur le fonctionnement du suivi, view [cet article](/developer-docs/feature-experimentation/technical-reference/faq-global#when-does-the-sdk-send-a-tracking-request-for-analytics)

##### Adding données points to target a utilisateur or filter / breakdown visits in reports

To target a utilisateur, ensure you've added relevant données points to their profil before retrieving the feature variation or checking if the flag est actif. Utilisez la [`addData()`](#adddata) method to add these données points to de l'utilisateur profil.

To retrieve données points collected on other devices or to access past utilisateur données (collected client-side when using Kameleoon in Hybrid mode), utilisez la [`getRemoteVisitorData()`](#getremotevisiteurdonnees) method. Cette méthode asynchronously fetches données from the servers. C'est important to call `getRemoteVisitorData()` *before* retrieving the variation or checking if the feature flag est actif, as this données might be required to assign a utilisateur to a given variation.

To learn more about available ciblage conditions, consultez la section [detailed article on the subject](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation).

De plus, les données points you add to le visiteur profil sera available when analyzing your expériences, allowing you to filter and break down your résultats by factors like device and browser. Kameleoon Hybrid mode automatically collects a variety of données points on le client-side, making it easy to break down your résultats basé sur these pre-collected données points. Consultez la section complète list [here](/fr/user-manual/experiment-analytics/analyze-results/results-page/results-page-settings#ventiler-l’audience).

Si vous avez besoin de track additional données points beyond what's automatically collected, vous pouvez utiliser Kameleoon's [Custom Data feature](#customdata). Custom Données allows you to capture and analyze specific informations relevant to your expériences. Don't forget to call the [`flush()`](#flush) method to send the collected données to Kameleoon servers for analysis.

<Note>
  To ensure your résultats are accurate, c'est recommended to filter out bots by en utilisant la fonction [`UserAgent`](#useragent) données type.
</Note>

##### Suivi objectif conversions

When a utilisateur complètes a desired action (tel que making a purchase), c'est recorded as a conversion. To track conversions, utilisez la [`trackConversion()`](#trackconversion) method and provide the required `visitorCode` and `goalId` parameters.

The conversion suivi request sera sent along with the next scheduled suivi request, which le SDK sends at regular intervals (defined by [`tracking_interval_millisecond`](#configuration-parameters)). If you préférez envoyer la requête immédiatement, utilisez la [`flush()`](#flush) method with le paramètre `instant=true`.

##### Sending événements to analytics solutions

To track conversions and send exposure événements to your customer analytics solution, vous devez first implement Kameleoon in [Hybrid mode](/developer-docs/feature-experimentation/get-started/hybrid-experimentation/). Then, utilisez la [`getEngineTrackingCode()`](#getenginesuivicode) method.

The `getEngineTrackingCode()` method retrieves the unique suivi code required to send exposure événements to your analytics solution. Using cette méthode allows you to record événements and send them to your desired analytics platform.

### React Native considerations

<Note>
  React Native on `android` platform ne support `Real Time Update` feature.
</Note>

While React SDK works the same way in both React Native and React contexts, c'est important to notez que setup steps differ.
Due to the lack of browser API in React Native, React SDK has to have different [external dependency](#external-dependencies) implementations to work correctly.
For that, Kameleoon provides several dedicated npm packages that vous pouvez install and set up manually or install using [Kameleoon SDK Installation Tool](#installation) (recommended).

The packages include:

* `@kameleoon/react-native-storage` - built using `react-native-mmkv` library
* `@kameleoon/react-native-event-source` - built using `react-native-event-source-ts` library
* `@kameleoon/react-native-visitor-code-manager` - built on top of `react-native-mmkv` library
* `@kameleoon/react-native-platform-analyzer` - built using `react-native` library
* *optional* `@kameleoon/react-native-secure-prng` - built using `react-native-get-random-values` library

If you don't want to utilisez la listed packages, vous pouvez provide your own implementation following [the external dependencies guide](#external-dependencies).

Example React SDK setup for React Native application:

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { createClient } from '@kameleoon/react-sdk';
    import { KameleoonEventSource } from '@kameleoon/react-native-event-source';
    import { KameleoonStorage } from '@kameleoon/react-native-storage';
    import { KameleoonVisitorCodeManager } from '@kameleoon/react-native-visitor-code-manager';
    import { KameleoonSecurePRNG } from '@kameleoon/react-native-secure-prng';
    import { KameleoonPlatformAnalyzer } from '@kameleoon/react-native-platform-analyzer';

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        storage: new KameleoonStorage(),
        eventSource: new KameleoonEventSource(),
        visitorCodeManager: new KameleoonVisitorCodeManager(),
        platformAnalyzer: new KameleoonPlatformAnalyzer(),
        // -- Optional --
        prng: new KameleoonSecurePRNG(),
      },
    });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { createClient } from '@kameleoon/react-sdk';
    import { KameleoonEventSource } from '@kameleoon/react-native-event-source';
    import { KameleoonStorage } from '@kameleoon/react-native-storage';
    import { KameleoonVisitorCodeManager } from '@kameleoon/react-native-visitor-code-manager';
    import { KameleoonSecurePRNG } from '@kameleoon/react-native-secure-prng';
    import { KameleoonPlatformAnalyzer } from '@kameleoon/react-native-platform-analyzer';

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        storage: new KameleoonStorage(),
        eventSource: new KameleoonEventSource(),
        visitorCodeManager: new KameleoonVisitorCodeManager(),
        platformAnalyzer: new KameleoonPlatformAnalyzer(),
        // -- Optional --
        prng: new KameleoonSecurePRNG(),
      },
    });
    ```
  </Tab>
</Tabs>

### Using a custom bucketing key

Par défaut, Kameleoon uses a unique, anonymous visiteur ID (`visitorCode`) to assign utilisateurs to feature flag variations. This ID is typically generated and stored on de l'utilisateur device (in a browser cookie for client-side and server-side SDKs—in persistent storage for mobile SDKs). Cependant, in certain scenarios vous pouvez need to ensure all utilisateurs of the same organization consultez la section same variant of a feature flag.

The **Custom Bucketing Key** option allows you to override this default behavior by providing your own custom identifier for bucketing. This override ensures that Kameleoon's assignment logic uses your specified key au lieu de the default `visitorCode`.

#### Use cases

Using a custom bucketing key is essential for maintaining consistency and accuracy in your feature flag assignments, particularly in these situations:

* **Account-level or organizational expériences:** For B2B products or scenarios where you want to assign all utilisateurs from the same organization to the same variation, vous pouvez utiliser an identifier like an `accountId`. Custom bucketing keys are crucial for A/B testing features that impact an entire team or company.

By implementing a custom bucketing key, you ensure greater consistency and accuracy in your expériences, leading to more reliable résultats and a better utilisateur expérience.

#### Technical détails

Lorsque vous configuré a custom bucketing key for a feature flag, you provide Kameleoon with a specific identifier from your application's données:

```jsx theme={null}
addData(visitorCode, new CustomData(index, 'newVisitorCode'));
```

<Tip>
  [More informations in addData()](#adddata)
</Tip>

* **Providing the custom key:** You provide your custom identifier to the Kameleoon SDK en utilisant la fonction [`addData()`](#adddata) method. In cette méthode, vous allez pass your chosen custom bucketing key as a [`CustomData`](#customdata) object. Here, `newVisitorCode` refers to the identifier you wish to use for your bucketing (par exemple, the new `userId` or `accountId`).

<Warning>
  For the custom bucketing key to function correctly, it must also be defined and configured for the feature flag during the flag création or editing process. Without this corresponding configuration, le SDK's bucketing will not apply your custom key. For detailed instructions on how to set this up in Kameleoon, consultez this [article](/user-manual/experimentation/feature-experimentation/create-and-manage-flags/create-a-feature-flag#Advanced_Flag_Settings).
</Warning>

* **Bucketing logic:** Once a custom bucketing key is provided through the `addData()` method, all hash calculations for assigning utilisateurs to variations will use this `newVisitorCode` (your custom key) au lieu de the default `visitorCode`. Using the `newVisitorCode` means that the bucketing decision is tied to your custom identifier, ensuring consistent assignments across various contexts where that identifier is present.
* **Données suivi and analytics:** C'est crucial to notez que while the `newVisitorCode` (your custom key) is utilisé pour bucketing decisions, **all subsequent données (suivi événements and conversions, par exemple) is sent and associated with the *original* `visitorCode`.** This separation ensures that your analytics accurately reflect individual utilisateur journeys and interactions within your expérience's broader context, even when bucketing is performed at a higher level (like an account) or across multiple devices/sessions. Votre original visiteur données remains intact for comprehensive reporting.

#### Technical requirementes

To effectively use a custom bucketing key:

* The key doit étre a `string`.
* It doit étre unique for the entity you intend to bucket (par exemple, if using a `userId`, each utilisateur's ID devrait étre unique).
* The key doit étre available to le SDK at the exact moment the feature flag decision is evaluated for that utilisateur or request.

### Ciblage conditions

The Kameleoon SDKs support a variety of predefined ciblage conditions that vous pouvez utiliser to target utilisateurs in your campaigns.
For la liste des conditions supported by this SDK, see [use visit history to target utilisateurs](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation).

Vous pouvez également use your own [external données to target utilisateurs](/developer-docs/feature-experimentation/targeting-and-segmentation/use-external-data-to-target-users).

### Logging

The SDK generates logs to reflect various internal processes and issues.

#### Log levels

The SDK supports configuring limiting logging by a log level.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { KameleoonClient, KameleoonLogger, LogLevel } from '@kameleoon/react-sdk';

    const client = createClient({ siteCode: 'my_site_code', configuration });

    // The `NONE` log level does not allow logging.
    client.setLogLevel(LogLevel.NONE);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.NONE);


    // The `ERROR` log level only allows logging issues that may affect the SDK's main behaviour.
    client.setLogLevel(LogLevel.ERROR);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.ERROR);

    // The `WARNING` log level allows logging issues which may require additional attention.
    // It extends the `ERROR` log level.
    // The `WARNING` log level is a default log level.
    client.setLogLevel(LogLevel.WARNING);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.WARNING);
    ```

    ```ts theme={null}
    import { KameleoonClient, KameleoonLogger, LogLevel } from '@kameleoon/react-sdk/full';

    // The `INFO` log level allows logging general information on the SDK's internal processes.
    // It extends the `WARNING` log level.
    client.setLogLevel(LogLevel.INFO);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.INFO);

    // The `DEBUG` level logs additional details about the SDK's internal processes and extends the `INFO` level
    // with more granular. diagnostic output.
    // This information is not intended for end-user interpretation but can be sent to our support team
    // to assist with internal troubleshooting.
    client.setLogLevel(LogLevel.DEBUG);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.DEBUG);
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { KameleoonClient, KameleoonLogger, LogLevel } from '@kameleoon/react-sdk';

    const client = createClient({ siteCode: 'my_site_code', configuration });

    // The `NONE` log level allows no logging.
    client.setLogLevel(LogLevel.NONE);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.NONE);


    // The `ERROR` log level only allows logging issues that may affect the SDK's main behaviour.
    client.setLogLevel(LogLevel.ERROR);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.ERROR);

    // The `WARNING` log level allows logging issues which may require additional attention.
    // It extends the `ERROR` log level.
    // The `WARNING` log level is a default log level.
    client.setLogLevel(LogLevel.WARNING);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.WARNING);
    ```

    ```js theme={null}
    import { KameleoonClient, KameleoonLogger, LogLevel } from '@kameleoon/react-sdk/full';

    // The `INFO` log level allows logging general information on the SDK's internal processes.
    // It extends the `WARNING` log level.
    client.setLogLevel(LogLevel.INFO);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.INFO);

    // The `DEBUG` level logs additional details about the SDK's internal processes and extends the `INFO` level
    // with more granular. diagnostic output.
    // This information is not intended for end-user interpretation but can be sent to our support team
    // to assist with internal troubleshooting.
    client.setLogLevel(LogLevel.DEBUG);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.DEBUG);
    ```
  </Tab>
</Tabs>

#### Custom handling of logs

The SDK writes its logs to the console output par défaut. This behaviour peut être overridden.

<Note>
  Logging limiting by a log level is performed apart from the log handling logic.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { KameleoonClient, KameleoonLogger, IExternalLogger, LogLevel } from '@kameleoon/react-sdk';

    export class CustomLogger implements IExternalLogger {
      // `log` method accepts logs from the SDK
      public log(level: LogLevel, message: string): void {
        // Custom log handling logic here. For example:
        switch (level) {
          case LogLevel.DEBUG:
            console.debug(message);
            break;
          case LogLevel.INFO:
            console.info(message);
            break;
          case LogLevel.WARNING:
            console.warn(message);
            break;
          case LogLevel.ERROR:
            console.error(message);
            break;
        }
      }
    }

    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        logger: new CustomLogger(),
      },
    });

    // Log level filtering is applied separately from log handling logic.
    // The custom logger will only accept logs that meet or exceed the specified log level.
    // Ensure the log level is set correctly.
    client.setLogLevel(LogLevel.DEBUG);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.DEBUG);
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { KameleoonClient, KameleoonLogger, LogLevel } from '@kameleoon/react-sdk';

    export class CustomLogger {
      // `log` method accepts logs from the SDK
      log(level, message) {
        // Custom log handling logic here. For example:
        switch (level) {
          case 'DEBUG':
            console.debug(message);
            break;
          case 'INFO':
            console.info(message);
            break;
          case 'WARNING':
            console.warn(message);
            break;
          case 'ERROR':
            console.error(message);
            break;
        }
      }
    }

    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        logger: new CustomLogger(),
      },
    });

    // Log level filtering is applied separately from log handling logic.
    // The custom logger will only accept logs that meet or exceed the specified log level.
    // Ensure the log level is set correctly.
    client.setLogLevel(LogLevel.DEBUG);
    // Or use KameleoonLogger
    KameleoonLogger.setLogLevel(LogLevel.DEBUG);
    ```
  </Tab>
</Tabs>

### Domain informations

You provide a domain as the `domain` in `KameleoonClient` \[configuration], qui est utilisé pour storing Kameleoon visiteur code in cookies. This is important when working with the [`getVisitorCode`](#getvisitorcode) and [`setLegalConsent`](#setlegalconsent) methods. The domain you provide is stored in the cookie as the `Domain=` key.

#### Setting the domain

The domain you provide indicates the URL address can utilisez la cookie. Par exemple, if your domain is `www.example.com`. the cookie is only available from a `www.example.com` URL. That means that pages with the `app.example.com` domain can't utilisez la cookie.

To be more flexible around subdomains, vous pouvez prefix a domain with `.`. Par exemple, the domain `.example.com` allows the cookie to function on both `app.example.com` and `login.example.com`.

<Note>
  Vous pouvez't use regular expressions, special symbols, protocol, or port numbers in the `domain`.
  De plus, a [specific liste de subdomains](https://publicsuffix.org/list/public_suffix_list.dat) ne sont pas allowed to be used with the prefix `.`.
</Note>

Here's a small domain cheat sheet:

| Domain                         | Allowed URLs          | Disallowed URLs      |
| ------------------------------ | --------------------- | -------------------- |
| `www.example.com`              | ✅`www.example.com`    | ❌ `app.example.com`  |
|                                | ✅ `example.com`       | ❌ `.com`             |
|                                |                       |                      |
| `.example.com` = `example.com` | ✅ `example.com`       | ❌ `otherexample.com` |
|                                | ✅ `www.example.com`   |                      |
|                                | ✅ `app.example.com`   |                      |
|                                | ✅ `login.example.com` |                      |
| `https://www.example.com`      | ⛔ bad domain          | ⛔ bad domain         |
| `www.example.com:4408`         | ⛔ bad domain          | ⛔ bad domain         |
| `.localhost.com` = `localhost` | ⛔ bad domain          | ⛔ bad domain         |

#### Developing on localhost

`localhost` est unlways considered a bad domain, making it hard to test the domain when developing on localhost.

There are two ways to avoid this issue:

* Don't specify the `domain` champ in le SDK client while testing. This empêche `localhost` issues (the cookie sera set on any domain).
* Create a local domain for `localhost`. Par exemple:
  * Navigate to `/etc/hosts` on *Linux* or to `c:\Windows\System32\Drivers\etc\hosts` on *Windows*
  * Open `hosts` with fichier super utilisateur or administrator rights
  * Add a domain to the localhost port, par exemple: `127.0.0.1 app.com`
  * Now vous pouvez run your app locally on `app.com:{my_port}` and specify `.app.com` as your domain

### External dependencies

SDK external dependencies utilisez la *dependency injection* pattern to give you the ability to provide your own implementations for certain parts of an SDK.

<Note>
  In the React SDK, all external dependencies have default implementations, which use a native browser API so there's no need to provide them unless another API est requis for specific use cases.
</Note>

Here's la liste des available external dependencies:

| Dependency                        | Interface                     | API Used                                          | Description                                                                                                                                                                                     |
| --------------------------------- | ----------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage` (*optional*)            | `IExternalStorage`            | Browser `localStorage`                            | Used for storing all the existing and collected SDK données                                                                                                                                     |
| `requester` (*optional*)          | `IExternalRequester`          | Browser `fetch`                                   | Used for performing all the network requests                                                                                                                                                    |
| `eventSource` (*optional*)        | `IExternalEventSource`        | Browser `EventSource`                             | Used for receiving Server Sent Événements for [Real Time Update](/fr/developer-docs/feature-experimentation/technical-reference/technical-considerations#streaming-option-premium) capabilities |
| `visitorCodeManager` (*optional*) | `IExternalVisitorCodeManager` | Browser cookie                                    | Used for storing and synchronizing visiteur code                                                                                                                                                |
| `prng` (*optional*)               | `IExternalPRNG`               | `Math.random` or Browser `crypto.getRandomValues` | Used to generate unique IDs for suivi événements                                                                                                                                                |
| `logger` (*optional*)             | `ILogger`                     | Custom implementation                             | Used for custom handling of logs from le SDK. Allows to define how logs are processed and where they are output.                                                                                |
| `platformAnalyzer` (*optional*)   | `IPlatformAnalyzer`           | React Native API                                  | Automatically detects the platform and attaches this informations to le visiteur données. Designed specifically for React Native.                                                               |

L'exemple suivant implements external dependencies. To import an interface from an SDK, create a class that implements it and pass the instantiated class to le SDK.

#### Storage

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { IExternalStorage } from '@kameleoon/react-sdk';

    // --- External Storage implementation ---
    // - JavaScript `Map` is used as an example storage
    const storage = new Map();

    class MyStorage<T> implements IExternalStorage<T> {
      public read(key: string): T | null {
        // - Read data using `key`
        const data = storage.get(key);

        // - Return `null` if there's no data
        if (!data) {
          return null;
        }

        // - Return obtained data
        return data;
      }

      public write(key: string, data: T): void {
        // - Write data using `key`
        storage.set(key, data);
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        storage: new MyStorage(),
      },
    });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { KameleoonClient } from '@kameleoon/react-sdk';

    // --- External Storage implementation ---
    // - JavaScript `Map` is used as an example storage
    const storage = new Map();

    class MyStorage {
      read(key) {
        // - Read data using `key`
        const data = storage.get(key);

        // - Return `null` if there's no data
        if (!data) {
          return null;
        }

        // - Return obtained data
        return data;
      }

      write(key, data) {
        // - Write data using `key`
        storage.set(key, data);
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        storage: new MyStorage(),
      },
    });
    ```
  </Tab>
</Tabs>

#### EvenementSource

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import {
      IExternalEventSource,
      EventSourceOpenParametersType,
    } from '@kameleoon/react-sdk';

    // --- External EventSource implementation ---
    // - Example uses native browser `EventSource`
    class MyEventSource implements IExternalEventSource {
      private eventSource?: EventSource;

      public open({
        eventType,
        onEvent,
        url,
      }: EventSourceOpenParametersType): void {
        // - Initialize `EventSource`
        const eventSource = new EventSource(url);

        this.eventSource = eventSource;
        // - Add event listener with provided event type and event callback
        this.eventSource.addEventListener(eventType, onEvent);
      }

      public close(): void {
        // - Cleanup open event source
        if (this.eventSource) {
          this.eventSource.close();
        }
      }

      public onError(callback: (error: Event) => void): void {
        // - Set error callback
        if (this.eventSource) {
          this.eventSource.onerror = callback;
        }
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        eventSource: new MyEventSource(),
      },
    });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    // --- External EventSource implementation ---
    // - Example uses native browser `EventSource`
    class MyEventSource {
      eventSource;

      open({ eventType, onEvent, url }) {
        // - Initialize `EventSource`
        const eventSource = new EventSource(url);

        this.eventSource = eventSource;
        // - Add event listener with provided event type and event callback
        this.eventSource.addEventListener(eventType, onEvent);
      }

      close() {
        // - Cleanup open event source
        if (this.eventSource) {
          this.eventSource.close();
        }
      }

      public onError(callback) {
        // - Set error callback
        if (this.eventSource) {
          this.eventSource.onerror = callback;
        }
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        eventSource: new MyEventSource(),
      },
    });
    ```
  </Tab>
</Tabs>

#### VisitorCodeManager

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import {
      IExternalVisitorCodeManager,
      SetDataParametersType,
      KameleoonUtils,
    } from '@kameleoon/react-sdk';

    // --- External Visitor Code Manager implementation ---
    // - Example uses browser `document.cookie` API
    class MyVisitorCodeManager implements IExternalVisitorCodeManager {
      public getData(key: string): string | null {
        const cookieString = document.cookie;

        // - Return `null` if no cookie was found
        if (!cookieString) {
          return null;
        }

        // - Parse cookie using provided `key`
        return KameleoonUtils.getCookieValue(cookieString, key);
      }

      public setData({
        visitorCode,
        domain,
        maxAge,
        key,
        path,
      }: SetDataParametersType): void {
        // - Set cookie with provided parameters
        let resultCookie = `${key}=${visitorCode}; Max-Age=${maxAge}; Path=${path}`;

        if (domain) {
          resultCookie += `; Domain=${domain}`;
        }

        document.cookie = resultCookie;
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        visitorCodeManager: new MyVisitorCodeManager(),
      },
    });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { KameleoonUtils } from '@kameleoon/react-sdk';

    // --- External Visitor Code Manager implementation ---
    // - Example uses browser `document.cookie` API
    class MyVisitorCodeManager {
      getData(key) {
        const cookieString = document.cookie;

        // - Return `null` if no cookie was found
        if (!cookieString) {
          return null;
        }

        // - Parse cookie using provided `key`
        return KameleoonUtils.getCookieValue(cookieString, key);
      }

      setData({ visitorCode, domain, maxAge, key, path }) {
        // - Set cookie with provided parameters
        let resultCookie = `${key}=${visitorCode}; Max-Age=${maxAge}; Path=${path}`;

        if (domain) {
          resultCookie += `; Domain=${domain}`;
        }

        document.cookie = resultCookie;
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        visitorCodeManager: new MyVisitorCodeManager(),
      },
    });
    ```
  </Tab>
</Tabs>

#### Requester

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import {
      RequestType,
      IExternalRequester,
      KameleoonResponseType,
      SendRequestParametersType,
    } from '@kameleoon/react-sdk';

    // --- External Requester Implementation
    export class MyRequester implements IExternalRequester {
      public async sendRequest({
        url,
        parameters,
      }: SendRequestParametersType<RequestType>): Promise<KameleoonResponseType> {
        // - Using native browser `fetch`
        return await fetch(url, parameters);
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        requester: new MyRequester(),
      },
    });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { KameleoonClient } from '@kameleoon/react-sdk';

    // --- External Requester Implementation
    export class MyRequester {
      async sendRequest({ url, parameters }) {
        // - Using native browser `fetch`
        return await fetch(url, parameters);
      }
    }

    // --- Create KameleoonClient ---
    const client = new KameleoonClient({
      siteCode: 'my_site_code',
      externals: {
        requester: new MyRequester(),
      },
    });
    ```
  </Tab>
</Tabs>

<Tip>
  [Return mocked résultat](#simulatesuccessrequest)
</Tip>

#### Pseudo Random Number Generator

Pseudo Random Number Generator (PRNG) est un dependency that generates random floating point number between `0` and `1` (similar to `Math.random`).

Default Kameleoon implementation relies on Browser's `crypto` or `Math.random` function if `crypto` n'est pas available.
Those API are very secure and reliable, cependant in some edge cases (especially in some `React Native` engines) you might want to provide your own implementation or use a dedicated Kameleoon package for React Native - `@kameleoon/react-native-secure-prng`

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { IExternalPRNG } from '@kameleoon/react-sdk';

    // --- External Pseudo Random Number Generator (PRNG) implementation ---
    class MyPRNG implements IExternalPRNG {
      public getRandomNumber(): number {
        // Return a random floating point number between `0` and `1`, like `Math.random()` does.
        return Math.random();
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        prng: new MyPRNG(),
      },
    });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    // --- External Pseudo Random Number Generator (PRNG) implementation ---
    class MyPRNG {
      getRandomNumber() {
        // Return a random floating point number between `0` and `1`, like `Math.random()` does.
        return Math.random();
      }
    }

    // --- Create KameleoonClient ---
    const client = createClient({
      siteCode: 'my_site_code',
      externals: {
        prng: new MyPRNG(),
      },
    });
    ```
  </Tab>
</Tabs>

### Erreur Handling

Almost every React SDK callback qui est returned by hooks may throw an erreur at some point, these erreurs ne sont pas just caveats but rather deliberately predefined `KameleoonError`s
that extend native JavaScript `Error` class providing useful messages and special `type` champ with a type `KameleoonException`.

`KameleoonException` est un enum containing all possible erreur types.

To know exactly what type of `KameleoonException` the callbacks may throw, vous pouvez check `Throws` section of le hooks description on this page or just hover over the callback in your IDE to see jsdocs description.

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

***

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useVisitorCode,
      useData,
      CustomData,
      KameleoonError,
      KameleoonException,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { addData } = useData();

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

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

          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, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useVisitorCode,
      useData,
      CustomData,
      KameleoonException,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { addData } = useData();

      const init = useCallback(async () => {
        try {
          await initialize();

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

          const customData = new CustomData(0, 'my_data');
          addData(visitorCode, customData);
        } catch (error) {
          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, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

### Cross-device experimentation

To support visiteurs who access an app from multiple devices, Kameleoon allows the synchronization of previously collected visiteur données across each of du visiteur devices and reconciliation of their visit history across devices through cross-device experimentation. Case studies and detailed informations on how Kameleoon handles données across devices are available in the [article on cross-device experimentation](/developer-docs/cross-device-experimentation).

#### Synchronizing données personnalisées across devices

Although custom mapping synchronization est utilisé pour align visiteur données across devices, it n'est pas always necessary. Below are two scenarios where custom mapping sync n'est pas required:

**Same utilisateur ID across devices**
If the same utilisateur ID is used consistently across all devices, synchronization is handled automatically without a custom mapping sync. C'est enough to call the `getRemoteVisitorData()` method lorsque vous want to sync les données collected between multiple devices.

**Multi-server instances with consistent IDs**
In complex setups involving multiple servers (par exemple, distributed server instances), where the same utilisateur ID est unvailable across servers, synchronization between servers (with `getRemoteVisitorData()`) is sufficient without additional custom mapping sync.

Customers who need additional données can consultez the [`getRemoteVisitorData()`](#getremotevisiteurdonnees) method description for further guidance. In the below code, c'est assumed that the same unique identifier (in this case, the `visitorCode`, which can also be referred to as `userId`) is used consistently between the two devices for accurate données retrieval.

<Note>
  Si vous voulez sync collected données in real time, vous devez choose the scope **Visiteur** for your données personnalisées.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx title="Device One" theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, CustomData } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { addData, flush } = useData();

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

        // -- Custom Data with index `0` was set to `Visitor` scope
        //    in Kameleoon.
        const customDataIndex = 0;
        const customData = new CustomData(customDataIndex, 'my_data');

        addData('my_visitor', customData);
        flush();
      }, [initialize, addData]);

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

    ```tsx title="Device Two" theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, CustomData } from '@kameleoon/react-sdk';

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

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

        // -- Before working with data, call `getRemoteVisitorData`.
        await getRemoteVisitorData({ visitorCode: 'my_visitor_code' });

        // -- New SDK code will have access to CustomData with `Visitor` scope
        //    defined on Device One.
        //    So, "my_data" is now available to target and track "my_visitor".
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx title="Device One" theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, CustomData } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData, flush } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Custom Data with index `0` was set to `Visitor` scope
        //    in Kameleoon.
        const customDataIndex = 0;
        const customData = new CustomData(customDataIndex, 'my_data');

        addData('my_visitor', customData);
        flush();
      }, [initialize, addData]);

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

    ```jsx title="Device Two" theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, CustomData } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getRemoteVisitorData } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Before working with data, call `getRemoteVisitorData`.
        await getRemoteVisitorData({ visitorCode: 'my_visitor_code' });

        // -- New SDK code will have access to CustomData with `Visitor` scope
        //    defined on Device One.
        //    So, "my_data" is now available to target and track "my_visitor".
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

#### Using données personnalisées for session merging

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    [Cross-device experimentation](/developer-docs/cross-device-experimentation) allows you to combine a visiteur's history across each of their devices (history reconciliation). One of the powerful features that history reconciliation provides est le ability to merge different visiteurs sessions into one. To reconcile visit history, vous pouvez utiliser [`CustomData`](#customdata) to provide a unique identifier for le visiteur.

    Follow the [activating cross-device history reconciliation](/fr/developer-docs/cross-device-experimentation#activer-la-réconciliation-d’historique-cross-device) guide to set up your données personnalisées on the Kameleoon platform

    Lorsque vousr données personnalisées is set up, vous pouvez utiliser it in your code to merge a visiteur's session.
    Sessions with the same identifier will always consultez la section same expérience variation and sera displayed as a single visiteur in the `Visitor` view of your expérience's résultat pages.

    The configuration SDK ensures that associated sessions always consultez la section same variation of the expérience.

    Afterwards, vous pouvez utiliser le SDK normally. The following methods might be helpful in the context of session merging:

    * Use [`getRemoteVisitorData`](#getremotevisiteurdonnees) with `isUniqueIdentifier=true` to retrieve données for all linked visiteurs
    * Use [`trackConversion`](#trackconversion) or [`flush`](#flush) with `isUniqueIdentifier=true` to track some données for specific visiteur that est unssociated with another visiteur

    <Tip>
      As the données personnalisées you use as the identifier doit étre set to `Visitor` scope, vous devez use [cross-device données personnalisées synchronization](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-données-across-devices) to retrieve the identifier with the [`getRemoteVisitorData`](#getremotevisiteurdonnees) method on each device.
    </Tip>

    Voici un exemple of how to use données personnalisées for session merging. Dans cet exemple, we have an application with a login page. Since we don't know l'utilisateur ID at the moment of login, we use an anonymous visiteur identifier generated by the [`getVisitorCode`](#getvisitorcode) method. After l'utilisateur logs in, we can associate the anonymous visiteur with l'utilisateur ID and use it as a unique identifier for le visiteur.

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx title="Login Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
        } from '@kameleoon/react-sdk';

        function LoginPage(): JSX.Element {
          const [visitorCode, setVisitorCode] = useState<string | null>(null);

          const { initialize } = useInitialize();
          const { getVariation } = useFeatureFlag();
          const { getVisitorCode } = useVisitorCode();

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

            const anonymousVisitor = getVisitorCode();
            // -- Saving `visitorCode` in the state to re-use it later.
            setVisitorCode(anonymousVisitor);

            // -- Getting a variation, assume it's variation `A`
            const variation = getVariation({
              visitorCode: anonymousVisitor,
              featureKey: 'my_feature_key',
            });
          }, [initialize, getVariation, getVisitorCode]);

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

        ```tsx title="Application Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useData,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
        } from '@kameleoon/react-sdk';

        type Props = {
          anonymousVisitor: string;
        };

        function ApplicationPage(props: Props): JSX.Element {
          const { addData, trackConversion, getRemoteVisitorData } = useData();
          const { getVariation } = useFeatureFlag();

          const init = useCallback(async (): Promise<void> => {
            // -- At this point anonymous visitor has logged in,
            //    and we have a user ID to use as a visitor identifier
            // -- Associating both visitors with an identifier Custom Data,
            //    where index `1` is the Custom Data's index, configured
            //    as a unique identifier in Kameleoon.
            const userIdentifierData = new CustomData(1, 'my_user_id');
            // -- Let's assume the anonymous visitor identifier
            //    was passed as a prop.
            addData(props.anonymousVisitor, userIdentifierData);

            // -- Retrieving the variation for the user ID ensures
            //    consistency with the anonymous visitor's variation.
            //    Both the anonymous visitor and the user ID will be
            //    assigned variation `A`.
            const variation = getVariation({
              visitorCode: 'my_user_id',
              featureKey: 'my_feature_key',
            });

            // -- `my_user_id` and `anonymousVisitor` are now linked.
            //    They can be tracked as a single visitor.
            trackConversion({
              visitorCode: 'my_user_id',
              goalId: 123,
              revenue: 100,
              // -- Informing the SDK that the visitor is a unique identifier
              isUniqueIdentifier: true,
            });

            // -- Additionally, linked visitors share previously
            //    collected remote data.
            const data = await getRemoteVisitorData({
              visitorCode: 'my_user_id',
              // -- Informing the SDK that the visitor is a unique identifier.
              isUniqueIdentifier: true,
            });
          }, [
            getRemoteVisitorData,
            trackConversion,
            addData,
            getVariation,
          ]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx title="Login Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
        } from '@kameleoon/react-sdk';

        function LoginPage() {
          const [visitorCode, setVisitorCode] = useState(null);

          const { initialize } = useInitialize();
          const { getVariation } = useFeatureFlag();
          const { getVisitorCode } = useVisitorCode();

          const init = useCallback(async () => {
            await initialize();

            const anonymousVisitor = getVisitorCode();
            // -- Saving `visitorCode` in the state to re-use it later.
            setVisitorCode(anonymousVisitor);

            // -- Getting a variation, assume it's variation `A`
            const variation = getVariation({
              visitorCode: anonymousVisitor,
              featureKey: 'my_feature_key',
            });
          }, [initialize, getVariation, getVisitorCode]);

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

        ```jsx title="Application Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useData,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
        } from '@kameleoon/react-sdk';

        function ApplicationPage(props) {
          const { addData, trackConversion, getRemoteVisitorData } = useData();
          const { getVariation } = useFeatureFlag();

          const init = useCallback(async () => {
            // -- At this point anonymous visitor has logged in,
            //    and we have a user ID to use as a visitor identifier
            // -- Associating both visitors with an identifier Custom Data,
            //    where index `1` is the Custom Data's index, configured
            //    as a unique identifier in Kameleoon.
            const userIdentifierData = new CustomData(1, 'my_user_id');
            // -- Let's assume the anonymous visitor identifier
            //    was passed as a prop.
            addData(props.anonymousVisitor, userIdentifierData);

            // -- Retrieving the variation for the user ID ensures
            //    consistency with the anonymous visitor's variation.
            //    Both the anonymous visitor and the user ID will be
            //    assigned variation `A`.
            const variation = getVariation({
              visitorCode: 'my_user_id',
              featureKey: 'my_feature_key',
            });

            // -- `my_user_id` and `anonymousVisitor` are now linked.
            //    They can be tracked as a single visitor.
            trackConversion({
              visitorCode: 'my_user_id',
              goalId: 123,
              revenue: 100,
              // -- Informing the SDK that the visitor is a unique identifier.
              isUniqueIdentifier: true,
            });

            // -- Additionally, linked visitors share previously
            //    collected remote data.
            const data = await getRemoteVisitorData({
              visitorCode: 'my_user_id',
              // -- Informing the SDK know the visitor is a unique identifier.
              isUniqueIdentifier: true,
            });
          }, [
            getRemoteVisitorData,
            trackConversion,
            addData,
            getVariation,
          ]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="SDK Version 10">
    [Cross-device experimentation](/developer-docs/cross-device-experimentation) allows you to combine a visiteur's history across each of their devices (history reconciliation). One of the powerful features that history reconciliation provides est le ability to merge different visiteurs sessions into one. To reconcile visit history, vous pouvez utiliser [`CustomData`](#customdata) to provide a unique identifier for le visiteur.

    Follow the [activating cross-device history reconciliation](/fr/developer-docs/cross-device-experimentation#activer-la-réconciliation-d’historique-cross-device) guide to set up your données personnalisées on the Kameleoon platform

    Lorsque vousr données personnalisées is set up, vous pouvez utiliser it in your code to merge a visiteur's session.
    Sessions with the same identifier will always consultez la section same expérience variation and sera displayed as a single visiteur in the `Visitor` view of your expérience's résultat pages.

    The SDK configuration ensures that associated sessions always consultez la section same variation of the expérience.

    Before using other methods assurez-vous to let SDK know that le visiteur est un unique identifier by adding [`UniqueIdentifier`](#uniqueidentifier) données to a visiteur

    <Tip>
      As the données personnalisées you use as the identifier doit étre set to `Visitor` scope, vous devez use [cross-device données personnalisées synchronization](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-données-across-devices) to retrieve the identifier with the [`getRemoteVisitorData`](#getremotevisiteurdonnees) method on each device.
    </Tip>

    Voici un exemple of how to use données personnalisées for session merging. Dans cet exemple, we have an application with a login page. Since we don't know l'utilisateur ID at the moment of login, we use an anonymous visiteur identifier generated by the [`getVisitorCode`](#getvisitorcode) method. After l'utilisateur logs in, we can associate the anonymous visiteur with l'utilisateur ID and use it as a unique identifier for le visiteur.

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx title="Login Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
        } from '@kameleoon/react-sdk';

        function LoginPage(): JSX.Element {
          const [visitorCode, setVisitorCode] = useState<string | null>(null);

          const { initialize } = useInitialize();
          const { getVariation } = useFeatureFlag();
          const { getVisitorCode } = useVisitorCode();

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

            const anonymousVisitor = getVisitorCode();
            // -- Saving `visitorCode` in the state to re-use it later.
            setVisitorCode(anonymousVisitor);

            // -- Getting a variation, assume it's variation `A`
            const variation = getVariation({
              visitorCode: anonymousVisitor,
              featureKey: 'my_feature_key',
            });
          }, [initialize, getVariation, getVisitorCode]);

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

        ```tsx title="Application Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useData,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
          UniqueIdentifier,
        } from '@kameleoon/react-sdk';

        type Props = {
          anonymousVisitor: string;
        };

        function ApplicationPage(props: Props): JSX.Element {
          const { addData, trackConversion, getRemoteVisitorData, flush } = useData();
          const { getVariation } = useFeatureFlag();

          const init = useCallback(async (): Promise<void> => {
            // -- At this point anonymous visitor has logged in,
            //    and we have a user ID to use as a visitor identifier
            // -- Associating both visitors with an identifier Custom Data,
            //    where index `1` is the Custom Data's index, configured
            //    as a unique identifier in Kameleoon.
            const userIdentifierData = new CustomData(1, 'my_user_id');
            // -- Let's assume the anonymous visitor identifier
            //    was passed as a prop.
            addData(props.anonymousVisitor, userIdentifierData);
            // -- Flushing data for the anonymous `visitorCode`
            flush(props.anonymousVisitor);

            // -- Informing the SDK that the visitor is unique identifier.
            addData('my_user_id', new UniqueIdentifier(true));

            // -- Retrieving the variation for the user ID ensures
            //    consistency with the anonymous visitor's variation.
            //    Both the anonymous visitor and the user ID will be
            //    assigned variation `A`.
            const variation = getVariation({
              visitorCode: 'my_user_id',
              featureKey: 'my_feature_key',
            });

            // -- `my_user_id` and `anonymousVisitor` are now linked.
            //    They can be tracked as a single visitor.
            trackConversion({
              visitorCode: 'my_user_id',
              goalId: 123,
              revenue: 100,
            });

            // -- Additionally, linked visitors share previously
            //    collected remote data.
            const data = await getRemoteVisitorData({
              visitorCode: 'my_user_id',
            });
          }, [
            getRemoteVisitorData,
            trackConversion,
            addData,
            getVariation,
          ]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx title="Login Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
        } from '@kameleoon/react-sdk';

        function LoginPage() {
          const [visitorCode, setVisitorCode] = useState(null);

          const { initialize } = useInitialize();
          const { getVariation } = useFeatureFlag();
          const { getVisitorCode } = useVisitorCode();

          const init = useCallback(async () => {
            await initialize();

            const anonymousVisitor = getVisitorCode();
            // -- Saving `visitorCode` in the state to re-use it later.
            setVisitorCode(anonymousVisitor);

            // -- Getting a variation, assume it's variation `A`
            const variation = getVariation({
              visitorCode: anonymousVisitor,
              featureKey: 'my_feature_key',
            });
          }, [initialize, getVariation, getVisitorCode]);

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

        ```jsx title="Application Page" theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useData,
          useFeatureFlag,
          useVisitorCode,
          CustomData,
          UniqueIdentifier,
        } from '@kameleoon/react-sdk';

        function ApplicationPage(props) {
          const { addData, trackConversion, getRemoteVisitorData, flush } = useData();
          const { getVariation } = useFeatureFlag();

          const init = useCallback(async () => {
            // -- At this point anonymous visitor has logged in,
            //    and we have a user ID to use as a visitor identifier
            // -- Associating both visitors with an identifier Custom Data,
            //    where index `1` is the Custom Data's index, configured
            //    as a unique identifier in Kameleoon.
            const userIdentifierData = new CustomData(1, 'my_user_id');
            // -- Let's assume the anonymous visitor identifier
            //    was passed as a prop.
            addData(props.anonymousVisitor, userIdentifierData);
            // -- Flushing data for the anonymous `visitorCode`
            flush(props.anonymousVisitor);

            // -- Informing the SDK that the visitor is a unique identifier.
            addData('my_user_id', new UniqueIdentifier(true));

            // -- Retrieving the variation for the user ID ensures
            //    consistency with the anonymous visitor's variation.
            //    Both the anonymous visitor and the user ID will be
            //    assigned variation `A`.
            const variation = client.getVariation({
              visitorCode: 'my_user_id',
              featureKey: 'my_feature_key',
            });

            // -- `my_user_id` and `anonymousVisitor` are now linked.
            //    They can be tracked as a single visitor.
            trackConversion({
              visitorCode: 'my_user_id',
              goalId: 123,
              revenue: 100,
            });

            // -- Additionally, linked visitors share previously
            //    collected remote data.
            const data = await getRemoteVisitorData({
              visitorCode: 'my_user_id',
            });
          }, [
            getRemoteVisitorData,
            trackConversion,
            addData,
            getVariation,
          ]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

### Utilities

SDK has a set of utility methods that peut être utilisé pour simplify the development process. All la méthodes are represented as static members of `KameleoonUtils` class.

#### simulateSuccessRequest

Method `simulateSuccessRequest` est utilisé pour simulate a successful request to the Kameleoon server. It peut être useful for custom [Requester](#requester) implementations when developer needs to simulate a successful request, par exemple disabling suivi.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import {
      KameleoonUtils,
      IExternalRequester,
      SendRequestParametersType,
      RequestType,
      KameleoonResponseType,
    } from '@kameleoon/react-sdk';

    // - Example of `Requester` with disabled tracking
    class Requester implements IExternalRequester {
      public async sendRequest({
        url,
        parameters,
        requestType,
      }: SendRequestParametersType<RequestType>): Promise<KameleoonResponseType> {
        if (requestType === RequestType.Tracking) {
          return KameleoonUtils.simulateSuccessRequest<RequestType.Tracking>(
            requestType,
            null,
          );
        }

        return await fetch(url, parameters);
      }
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { KameleoonUtils } from '@kameleoon/react-sdk';

    // - Example of `Requester` with disabled tracking
    class Requester {
      async sendRequest({ url, parameters, requestType }) {
        if (requestType === RequestType.Tracking) {
          return KameleoonUtils.simulateSuccessRequest(requestType, null);
        }

        return await fetch(url, parameters);
      }
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                     | Type                                   | Description                                                             |
| ------------------------ | -------------------------------------- | ----------------------------------------------------------------------- |
| requestType (*required*) | `RequestType`                          | A type of request                                                       |
| données (*required*)     | `SimulateRequestDataType[RequestType]` | A type of request données, qui est different depending on `RequestType` |

Données type `SimulateRequestDataType` is defined as follows:

* `RequestType.Tracking` - `null`
* `RequestType.ClientConfiguration` - `ClientConfigurationDataType`
* `RequestType.RemoteData` - `JSONType`

##### Valeur de retour

| Type                             | Description                                      |
| -------------------------------- | ------------------------------------------------ |
| `Promise<KameleoonResponseType>` | renvoie un promise with la réponse of la requête |

#### getCookieValue

Method `getCookieValue` est utilisé pour parse a common cookie string (`key_1=value_1; key_2=value_2; ...`) and get la valeur of a specific cookie key. C'est useful when working with a custom implementation of [`VisitorCodeManager`](#visitorcodemanager).

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { KameleoonUtils } from '@kameleoon/react-sdk';

    const cookies = 'key_1=value_1; key_2=value_2';
    const key = 'key_1';

    const value = KameleoonUtils.getCookieValue(cookies, key); // = `value_1`
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { KameleoonUtils } from '@kameleoon/react-sdk';

    const cookies = 'key_1=value_1; key_2=value_2';
    const key = 'key_1';

    const value = KameleoonUtils.getCookieValue(cookies, key); // = `value_1`
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                | Type     | Description                                            |
| ------------------- | -------- | ------------------------------------------------------ |
| cookie (*required*) | `string` | Cookie string in a form `key_1=value_1; key_2=value_2` |
| key (*required*)    | `string` | String representation of une clé to find une valeur by |

##### Valeur de retour

| Type     | Description |                                                                         |
| -------- | ----------- | ----------------------------------------------------------------------- |
| \`string | null\`      | renvoie un string with a cookie value or `null` if la clé was not found |

## Référence

C'est le full référence documentation for the React SDK.

### Initialization

This section provides la méthodes you use to create and initialize the Kameleoon Client in your application.

#### initialize()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    An asynchronous `initialize` function, collected with `useInitialize` hook, that's utilisé pour KameleoonClient initialization by fetching Kameleoon SDK related données from server or by retrieving données from local source if données is up-to-date or update interval has not been reached.

    <Note>
      * If le SDK configuration could not be retrieved but il y a an older configuration available in SDK storage, le SDK uses the older configuration as a fallback and the `initialize` ne fait pas throw an erreur.

      * Client initialization has une optional *offline mode*.
        C'est activated by setting optional `useCache` parameter to `true`.

      In *offline mode* if suivi requests from any of the following methods fail due to internet connectivity issues, le SDK automatically resends la requête as soon as it detects that the internet connection has been re-established:

      * [flush](#flush)
      * [trackConversion](#trackconversion)
      * [getFeatureFlagVairationKey](#getfeatureflagvariationkey)
      * [getFeatureVariable](#getfeatureflagvariable)
      * [sFeatureFlagActive](#isfeatureflagactive)
    </Note>

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        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]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useInitialize } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { initialize } = useInitialize();

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

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Arguments

    | Name                  | Type                     | Description                                                                                                                                                   | Default Value |
    | --------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
    | useCache (*optional*) | `boolean` or `undefined` | parameter for activating SDK offline mode, if `true` is passed failed polls will not return erreur and will use cached données if such données est unvailable | `false`       |

    ##### Valeur de retour

    | Type               | Description                                                                                                                                                                                                                                                                 |
    | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `Promise<boolean>` | a promise resolved to a boolean indicating a successful sdk initialization. Generally initialize will throw an erreur 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 informations. |

    ##### Exceptions thrown

    | Type                                       | Description                                               |
    | ------------------------------------------ | --------------------------------------------------------- |
    | `KameleoonException.StorageWrite`          | Couldn't update storage données                           |
    | `KameleoonException.ClientConfiguration`   | Couldn't retrieve client configuration from Kameleoon API |
    | `KameleoonException.MaximumRetriesReached` | Maximum retries reached, request failed                   |
  </Tab>

  <Tab title="SDK Version 10">
    An asynchronous `initialize` function, collected with `useInitialize` hook, that's utilisé pour KameleoonClient initialization by fetching Kameleoon SDK related données from server or by retrieving données from local source if données is up-to-date or update interval has not been reached.

    <Note>
      * If le SDK configuration could not be retrieved but il y a an older configuration available in SDK storage, le SDK uses the older configuration as a fallback and the `initialize` ne fait pas throw an erreur.

      * SDK supports an *offline mode*.

      In *offline mode* if suivi requests from any of the following methods fail due to internet connectivity issues, le SDK automatically resends la requête as soon as it detects that the internet connection has been re-established:

      * [flush](#flush)
      * [trackConversion](#trackconversion)
      * [getFeatureFlagVairationKey](#getfeatureflagvariationkey)
      * [getFeatureVariable](#getfeatureflagvariable)
      * [sFeatureFlagActive](#isfeatureflagactive)
    </Note>

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        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]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useInitialize } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { initialize } = useInitialize();

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

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Valeur de retour

    | Type               | Description                                                                                                                                                                                                                                                                 |
    | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `Promise<boolean>` | a promise resolved to a boolean indicating a successful sdk initialization. Generally initialize will throw an erreur 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 informations. |

    ##### Exceptions thrown

    | Type                                       | Description                                               |
    | ------------------------------------------ | --------------------------------------------------------- |
    | `KameleoonException.StorageWrite`          | Couldn't update storage données                           |
    | `KameleoonException.ClientConfiguration`   | Couldn't retrieve client configuration from Kameleoon API |
    | `KameleoonException.MaximumRetriesReached` | Maximum retries reached, request failed                   |
  </Tab>
</Tabs>

#### isInitialized()

The `isInitialized` function, collected with the `useInitialize` hook, est un small utility method that checks if le SDK initialization has completed. Par exemple, this peut être useful when dealing with a deeply nested component tree, because it allows you to quickly check le SDK readiness without having to manage a global state, or pass the initialization résultat using component props.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useFeatureFlag } from '@kameleoon/react-sdk';

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

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

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

    function DeeplyNestedComponent(): JSX.Element {
      const { isInitialized } = useInitialize();
      const { getVariation } = useFeatureFlag();

      if (isInitialized()) {
        const variation = getVariation({ visitorCode: 'visitor_code', featureKey: 'my_feature_key' });
      }
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useFeatureFlag } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();

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

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

    function DeeplyNestedComponent() {
      const { isInitialized } = useInitialize();
      const { getVariation } = useFeatureFlag();

      if (isInitialize()) {
        const variation = getVariation({ visitorCode: 'visitor_code', featureKey: 'my_feature_key' });
      }
    }
    ```
  </Tab>
</Tabs>

##### Valeur de retour

A `boolean` value. Renvoie `true` if SDK was successfully initialized, sinon renvoie `false`.

#### createClient()

To get started, vous devez create an entry point for React SDK by creating a Kameleoon Client at the top level of your application en utilisant la fonction `createClient()` function importé depuis `kameleoon` package.

An instance de `KameleoonClient` is created using `createClient()` function.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import {
      createClient,
      Environment,
      SDKConfigurationType,
    } from '@kameleoon/react-sdk';

    // -- Optional configuration
    const configuration: Partial<SDKConfigurationType> = {
      updateInterval: 60,
      environment: Environment.Production,
      cookieDomain: '.example.com',
    };

    const client = createClient({ siteCode: 'my_site_code', configuration });
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { createClient, Environment } from '@kameleoon/react-sdk';

    // -- Optional configuration
    const configuration = {
      updateInterval: 60,
      environment: Environment.Production,
      cookieDomain: '.example.com',
    };

    const client = createClient({ siteCode: 'my_site_code', configuration });
    ```
  </Tab>
</Tabs>

##### Arguments

An object of type `SDKParameters` containing:

| Name                       | Type                            | Description                                                                                                                                       |
| -------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| siteCode (*required*)      | `string`                        | Ceci est un [unique key](/user-manual/faq#how-do-i-find-my-sitecode) of the Kameleoon project you are using with le SDK. This champ is mandatory. |
| configuration (*optional*) | `Partial<SDKConfigurationType>` | client's configuration                                                                                                                            |
| externals (*optional*)     | `ExternalsType`                 | external implementation of SDK dependencies ([External dependencies](#external-dependencies))                                                     |

##### Configuration Parameters

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    | Name                                       | Type          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Default Value                           |
    | ------------------------------------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
    | updateInterval (*optional*)                | `number`      | Specifies the refresh interval, in minutes, that le SDK fetches the configuration for the active expériences and feature flags. The value determines the maximum time it takes to propagate changes, tel que activating or deactivating feature flags or launching expériences, to your production servers. If left unspecified, the default interval is set to 60 minutes. De plus, we offer a [streaming mode](/developer-docs/feature-experimentation/technical-reference/technical-considerations/#streaming-premium-option) that uses server-sent événements (SSE) to push new configurations to le SDK automatically and apply new configurations in real-time, without any delays. | `60`                                    |
    | environnement (*optional*)                 | `Environment` | feature flag environnement                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `Environment.Production`                |
    | ciblageDonneesCleanupInterval (*optional*) | `number`      | interval in *minutes* for cleaning up ciblage données; minimum value is 1 minute                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `undefined` (no cleanup sera performed) |
    | domain (*optional*)                        | `string`      | [domain](#domain-informations) that the cookie belongs to. Deprecated, use `cookieDomain` instead                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `undefined`                             |
    | cookieDomain (*optional*)                  | `string`      | [domain](#domain-informations) that the cookie belongs to.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `undefined`                             |
    | networkDomain (*optional*)                 | `string`      | custom domain le SDKs uses for all outgoing network requests, commonly utilisé pour proxying. The format is `second_level_domain.top_level_domain` (par exemple, `example.com`). If an invalid format is specified, le SDK uses the default Kameleoon value                                                                                                                                                                                                                                                                                                                                                                                                                               | `undefined`                             |
    | requestTimeout (*optional*)                | `number`      | timeout in *milliseconds* for all SDK network requests, if timeout is exceeded request will fail immediately                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `10_000` (10 seconds)                   |
    | suiviInterval (*optional*)                 | `number`      | Specifies the interval for suivi requests, in milliseconds. All visiteurs who were evaluated for any feature flag or had associated données sera included in this suivi request, qui est performed once per interval. The minimum value is `100` ms and the maximum value is `1_000` ms                                                                                                                                                                                                                                                                                                                                                                                                   | `1_000` (1 second)                      |

    <Note>
      The `domain` parameter is deprecated and sera removed in a future release. Use `cookieDomain` instead.
    </Note>
  </Tab>

  <Tab title="SDK Version 10">
    | Name                                       | Type                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Default Value                           |
    | ------------------------------------------ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
    | updateInterval (*optional*)                | `number`                | Specifies the refresh interval, in minutes, that le SDK fetches the configuration for the active expériences and feature flags. The value determines the maximum time it takes to propagate changes, tel que activating or deactivating feature flags or launching expériences, to your production servers. If left unspecified, the default interval is set to 60 minutes. De plus, we offer a [streaming mode](/developer-docs/feature-experimentation/technical-reference/technical-considerations/#streaming-premium-option) that uses server-sent événements (SSE) to push new configurations to le SDK automatically and apply new configurations in real-time, without any delays.                                     | `60`                                    |
    | environnement (*optional*)                 | `Environment \| string` | feature flag environnement                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `Environment.Production`                |
    | ciblageDonneesCleanupInterval (*optional*) | `number`                | interval in *minutes* for cleaning up ciblage données; minimum value is 1 minute                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `undefined` (no cleanup sera performed) |
    | cookieDomain (*optional*)                  | `string`                | [domain](#domain-informations) that the cookie belongs to.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `undefined`                             |
    | networkDomain (*optional*)                 | `string`                | custom domain le SDKs uses for all outgoing network requests, commonly utilisé pour proxying. The format is `second_level_domain.top_level_domain` (par exemple, `example.com`). If an invalid format is specified, le SDK uses the default Kameleoon value                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `undefined`                             |
    | requestTimeout (*optional*)                | `number`                | timeout in *milliseconds* for all SDK network requests, if timeout is exceeded request will fail immediately                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `10_000` (10 seconds)                   |
    | suiviInterval (*optional*)                 | `number`                | Specifies the interval for suivi requests, in milliseconds. All visiteurs who were evaluated for any feature flag or had associated données sera included in this suivi request, qui est performed once per interval. The minimum value is `1_000` ms and the maximum value is `5_000` ms                                                                                                                                                                                                                                                                                                                                                                                                                                     | `1_000` (1 second)                      |
    | stubMode (*optional*)                      | `boolean`               | When set to true, le client will operate in stub mode and perform no operations. In this mode, all method calls exécute no actions, ensuring that no external actions or side effects occur.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `false`                                 |
    | defaultDonneesFichier (*optional*)         | `string`                | The `defaultDataFile` feature ensures the Kameleoon SDK est unlways **READY** by providing a fallback configuration when no cached datun fichier exists. Developers can preload a valid configuration by fetching it from `https://sdk-config.kameleoon.eu/v3/<sitecode>` and passing it as `defaultDataFile` during initialization. When a `dateModified` timestamp (in milliseconds) is provided and is newer than the cached version, le SDK will utilisez la default donneesfichier au lieu de the cached version. **If `dateModified` is omitted, the default donneesfichier is only applied when no cached version exists**. This ensures le SDK always has a valid configuration, whether default, cached, or updated. | `undefined`                             |

    <Tip>
      **Option 1 (Recommended):** Use `JSON.stringify()`

      ```js theme={null}
      const dataFileJson = {"configuration":{"consentType":.....,
          {"key":"show_car","type":"JSON","value":"{\"make\":\"Porsche\",\"model\":\"911\"}"}},
          "dateModified":1752209266000};
      const dataFileString = JSON.stringify(dataFileJson);
      const configuration = {
        updateInterval: 20,
        defaultDataFile: dataFileString
      };
      ```

      **Option 2:** Raw JSON string (escape special characters)

      ```js theme={null}
      const configuration = {
        updateInterval: 20,
        defaultDataFile: `{"configuration":{"consentType":.....,
          {"key":"show_car","type":"JSON","value":"{\\"make\\":\\"Porsche\\",\\"model\\":\\"911\\"}"},
          "dateModified":1752209266000}`
      };
      ```
    </Tip>
  </Tab>
</Tabs>

##### Valeur de retour

| Type              | Description                      |
| ----------------- | -------------------------------- |
| `KameleoonClient` | une instance de KameleoonClient. |

<Note>
  Assurez-vous not to use several client instances in one application as it n'est pas fully supported yet and may overwrite the local storage configuration and cause unintended behavior (bugs).
</Note>

### Feature flags and variations

This section provides la méthodes you use to retrieve and manage the feature flags and variations assigned to le visiteur.

#### getVariation()

* 📨 *Sends Suivi Données to Kameleoon (depending on the `track` parameter)*

Retrieves the [`Variation`](#variation) assigned to a given visiteur for a specific feature flag.

Cette méthode takes `featureKey` as a mandatory argument and `track` as une optional argument. The `track` argument est optionnel and defaults to `true`.

It renvoie le assigned `Variation` for le visiteur. If le visiteur n'est pas associated with any feature flag rules, la méthode renvoie le default `Variation` for the given feature flag.

Ensure that proper erreur handling is implemented in your code to manage potential exceptions.

<Note>
  The default variation refers to the variation assigned to a visiteur when they ne pas match any predefined delivery rules for a feature flag. In other words, it est le fallback variation applied to all utilisateurs who ne sont pas targeted by specific rules. C'est represented as the variation in the "Then, for everyone else..." section in a management interface.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVariation } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

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

        // -- Get visitor code using `getVisitorCode` function
        const visitorCode = getVisitorCode();

        // -- Get variation with tracking
        const variation = getVariation({
          visitorCode,
          featureKey: 'my_feature_key',
        });

        // -- Get variation without tracking
        const variation = getVariation({
          visitorCode,
          featureKey: 'my_feature_key',
          track: false,
        });

        // -- An Example variation:
        // {
        //  key: 'variation_key',
        //  id: 123,
        //  experimentId: 456,
        //  variables: Map {
        //    'variable_key' => {
        //      key: 'variable_key',
        //      type: VariableType.BOOLEAN,
        //      value: true,
        //    }
        //  },
        // }
      }, [initialize, visitorCode, getVariation, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVariation } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

      const init = useCallback(async () => {
        await initialize();

        // -- Get visitor code using `getVisitorCode` function
        const visitorCode = getVisitorCode();

        // -- Get variation with tracking
        const variation = getVariation({
          visitorCode,
          featureKey: 'my_feature_key',
        });

        // -- Get variation without tracking
        const variation = getVariation({
          visitorCode,
          featureKey: 'my_feature_key',
          track: false,
        });

        // -- An Example variation:
        // {
        //  key: 'variation_key',
        //  id: 123,
        //  experimentId: 456,
        //  variables: Map {
        //    'variable_key' => {
        //      key: 'variable_key',
        //      type: VariableType.BOOLEAN,
        //      value: true,
        //    }
        //  },
        // }
      }, [initialize, visitorCode, getVariation, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

An object of type `GetVariationParamsType` with the following properties:

| Name                     | Type      | Description                                                                 | Default |
| ------------------------ | --------- | --------------------------------------------------------------------------- | ------- |
| visitorCode (*required*) | `string`  | Unique identifier of le visiteur.                                           |         |
| featureKey (*required*)  | `string`  | Key of the feature you want to expose to a visiteur.                        |         |
| track (*optional*)       | `boolean` | An optional parameter to enable or disable suivi of the feature evaluation. | `true`  |

##### Valeur de retour

| Type        | Description                                                                            |
| ----------- | -------------------------------------------------------------------------------------- |
| `Variation` | An assigned [`Variation`](#variation) to a given visiteur for a specific feature flag. |

##### Exceptions thrown

| Type                                                  | Description                                                                                                                                                                                                                                                            |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | Method was executed before the `kameleoonClient` completed c'est [`initialize`](#initialize) call.                                                                                                                                                                     |
| `KameleoonException.VisitorCodeEmpty`                 | The visiteur code is empty.                                                                                                                                                                                                                                            |
| `KameleoonException.VisitorCodeMaxLength`             | The visiteur code exceeded the maximum length (255 characters).                                                                                                                                                                                                        |
| `KameleoonException.FeatureFlagConfigurationNotFound` | Exception indicating that la requeteed feature key wasn't found in the internal configuration of le SDK. This usually means that the feature flag n'est pas activated in the Kameleoon app (but code implementing the feature est unlready deployed in l'application). |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Exception indicating that feature flag is disabled for du visiteur current environnement (par exemple, production, staging, or development).                                                                                                                           |

#### getVariations()

* 📨 *Sends Suivi Données to Kameleoon (depending on the `track` parameter)*
* 🎯 *Événements:* [`EventType.Evaluation`](#events-1)

<Info>
  Method is obtained using `useFeatureFlag` hook.
</Info>

Retrieves a map of [`Variation`](#variation) objects assigned to a given visiteur across all feature flags.

Cette méthode iterates over all available feature flags and renvoie le assigned `Variation` for each flag associated with the specified visiteur. It takes `visitorCode` as a mandatory argument, while `onlyActive` and `track` are optional.

* If `onlyActive` is set to `true`, la méthode `getVariations()` will return feature flags variations provided l'utilisateur n'est pas bucketed with the `off` variation.
* The `track` parameter controls whether or not la méthode will track the variation assignments. Par défaut, c'est set to `true`. If set to `false`, the suivi sera disabled.

The returned map consists of feature flag keys as keys and their corresponding `Variation` as values. If no variation est unssigned for a feature flag, la méthode renvoie le default `Variation` for that flag.

Proper erreur handling devrait étre implemented to manage potential exceptions.

<Note>
  The default variation refers to the variation assigned to a visiteur when they ne pas match any predefined delivery rules for a feature flag. In other words, it est le fallback variation applied to all utilisateurs who ne sont pas targeted by specific rules. C'est represented as the variation in the "Then, for everyone else..." section in a management interface.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVariations } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

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

        // -- Get visitor code using `getVisitorCode` function
        const visitorCode = getVisitorCode();

        // -- Get all feature flag variations with tracking
        const variations = getVariations({
          visitorCode,
        });

        // -- Get active feature flag variations with tracking
        const variations = getVariations({
          visitorCode,
          onlyActive: true,
        });

        // -- Get active feature flag variations without tracking
        const variations = getVariations({
          visitorCode,
          onlyActive: true,
          track: false,
        });

        // -- An Example variations:
        // Map {
        // 'feature_key' => {
        //    key: 'variation_key',
        //    id: 123,
        //    experimentId: 456,
        //    variables: Map {
        //      'variable_key' => {
        //        key: 'variable_key',
        //        type: VariableType.BOOLEAN,
        //        value: true,
        //      }
        //    },
        //   }
        // }
      }, [initialize, visitorCode, getVariations, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVariations } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

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

        // -- Get visitor code using `getVisitorCode` function
        const visitorCode = getVisitorCode();

        // -- Get all feature flag variations with tracking
        const variations = getVariations({
          visitorCode,
        });

        // -- Get active feature flag variations with tracking
        const variations = getVariations({
          visitorCode,
          onlyActive: true,
        });

        // -- Get active feature flag variations without tracking
        const variations = getVariations({
          visitorCode,
          onlyActive: true,
          track: false,
        });

        // -- An Example variations:
        // Map {
        // 'feature_key' => {
        //    key: 'variation_key',
        //    id: 123,
        //    experimentId: 456,
        //    variables: Map {
        //      'variable_key' => {
        //        key: 'variable_key',
        //        type: VariableType.BOOLEAN,
        //        value: true,
        //      }
        //    },
        //   }
        // }
      }, [initialize, visitorCode, getVariations, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

An object of type `GetVariationsParamsType` with the following properties:

| Name                     | Type      | Description                                                                                                       | Default |
| ------------------------ | --------- | ----------------------------------------------------------------------------------------------------------------- | ------- |
| visitorCode (*required*) | `string`  | Unique identifier of le visiteur.                                                                                 |         |
| onlyActive (*optional*)  | `boolean` | An optional parameter indicating whether to return variations for active (`true`) or all (`false`) feature flags. | `false` |
| track (*optional*)       | `boolean` | An optional parameter to enable or disable suivi of the feature evaluation.                                       | `true`  |

##### Valeur de retour

| Type                     | Description                                                                                                                        |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `Map<string, Variation>` | Map that contains the assigned [`Variation`](#variation) objects of the feature flags using la clés of the corresponding features. |

##### Exceptions thrown

| Type                                      | Description                                                                                        |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | Method was executed before the `kameleoonClient` completed c'est [`initialize`](#initialize) call. |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty.                                                                        |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters).                                    |

#### isFeatureFlagActive()

* 📨 *Sends Suivi Données to Kameleoon (depending on the `track` parameter)*
* 🎯 *Événements:* `EventType.Evaluation`

The method `isFeatureFlagActive()`, used with the `useFeatureFlag` hook, determines whether a visiteur identified by `visitorCode` has the specified `featureKey` active. Cette méthode checks the ciblage conditions, identifies the variation for le visiteur, and saves this informations to storage. De plus, le hook sends a suivi request.

There est unlso an overload for cette méthode that includes a `track` parameter, allowing you to disable the suivi of the feature evaluation.

<Note>
  Visiteur doit étre targeted to has feature flag active
</Note>

<Note>
  Kameleoon uses suivi to count sessions and visiteurs lorsque vous call certain methods, tel que `isFeatureFlagActive()`, `getVariation()` or `getVariations()`.

  Utilisez la default `true` value for the `track` parameter lorsque vous expose visiteurs to a variation and need to count them. Set the `track` parameter to `false` only if you call these methods before you expose visiteurs.

  Par exemple, if you call `getVariations()` to retrieve all variations before you expose visiteurs, set the `track` parameter to `false`. This setting empêche Kameleoon from prematurely counting a session. Vous pouvez then trigger suivi later lorsque vous explicitly expose le visiteur.

  Kameleoon sends suivi données every second par défaut. Vous pouvez configuré this interval up to five seconds en utilisant la fonction suivi interval configuration option. Kameleoon groups suivi événements into a single session as long as the interval between événements is less than 30 minutes. If more than 30 minutes elapse between suivi événements, Kameleoon counts the événements as separate sessions. A visit appears in your reports 30 minutes after the last recorded événement in the session.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      useFeatureFlag,
      useVisitorCode,
      CustomData,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { addData } = useData();
      const { isFeatureFlagActive } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

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

        // -- Get visitor code using `getVisitorCode` function
        const visitorCode = getVisitorCode();

        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);

        // -- Check if the feature flag is active for visitor without tracking
        const isActive = isFeatureFlagActive({ visitorCode, featureKey: 'my_feature', track: false});
      }, [initialize, visitorCode, isFeatureFlagActive, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      useFeatureFlag,
      useVisitorCode,
      CustomData,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();
      const { isFeatureFlagActive } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

      const init = useCallback(async () => {
        await initialize();

        // -- Get visitor code using `getVisitorCode` function.
        const visitorCode = getVisitorCode();

        const featureKey = 'my_feature_key';

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

        // -- Get the feature flag's status.
        const isActive = isFeatureFlagActive(visitorCode, featureKey);

        // -- Check if the feature flag is active for visitors without tracking.
        const isActive = isFeatureFlagActive({ visitorCode, featureKey: 'my_feature', track: false});
      }, [initialize, visitorCode, isFeatureFlagActive, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

<Warning>
  The `isFeatureFlagActive()` method evaluates the served variant, not the master flag state. If you exclude rules, la méthode uses the **Then, for everyone else serve** default state. If you select **Off** for this default state, la méthode always renvoie `false` even when the master feature flag is **On**.
</Warning>

##### Arguments

There are two overloads available for cette méthode:

1. Two parameters overload:

<Warning>
  This overload is deprecated and sera removed in the next major version. Please utilisez la new overload with an object parameter.
</Warning>

| Name                     | Type     | Description                                                               |
| ------------------------ | -------- | ------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | unique visiteur identification string, can't exceed 255 characters length |
| featureKey (*required*)  | `string` | a unique key for feature flag                                             |

2. Object parameter overload of type `IsFeatureFlagActiveParamsType`:

| Name                     | Type      | Description                                                               | Default |
| ------------------------ | --------- | ------------------------------------------------------------------------- | ------- |
| visitorCode (*required*) | `string`  | unique visiteur identification string, can't exceed 255 characters length | -       |
| featureKey (*required*)  | `string`  | a unique key for feature flag                                             | -       |
| track (*optional*)       | `boolean` | a boolean indicator of whether to track the feature evaluation            | `true`  |

##### Valeur de retour

| Type      | Description                                                                                        |
| --------- | -------------------------------------------------------------------------------------------------- |
| `boolean` | indicator of whether the feature flag with `featureKey` est actif for visiteur with `visitorCode`. |

##### Exceptions thrown

| Type                                                  | Description                                                                          |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `KameleoonException.Initialization`                   | Method was executed before the `kameleoonClient` completed c'est `initialize` call   |
| `KameleoonException.VisitorCodeMaxLength`             | The visiteur code exceeded the maximum length (255 characters)                       |
| `KameleoonException.VisitorCodeEmpty`                 | The visiteur code is empty                                                           |
| `KameleoonException.FeatureFlagConfigurationNotFound` | No feature flag was found for the specified `featureKey`                             |
| `KameleoonException.DataInconsistency`                | Allocated variation was found but il y a no feature flag with according `featureKey` |

***

#### setForcedVariation()

The method allows you to programmatically assign a specific [`Variation`](#variation) to a utilisateur, bypassing the standard evaluation process. This is especially valuable for controlled expériences where the usual evaluation logic n'est pas required or doit étre skipped. It can also be helpful in scenarios like debugging or custom testing.

When a **forced** variation is set, it overrides Kameleoon's real-time evaluation logic. Processes like segmentation, ciblage conditions, and algorithmic calculations are skipped. To preserve segmentation and ciblage conditions during an expérience, set `forceTargeting=false` instead.

<Info>
  **Simulated** variations always take precedence in the execution order. If a **simulated** variation calculation is triggered, it sera fully processed and completed first.
</Info>

A forced variation is treated the same as an evaluated variation. C'est tracked in analytics and stored in l'utilisateur context like any standard evaluated variation, ensuring consistency in reporting.

The method may throw exceptions under certain conditions (e.g., invalid parameters, utilisateur context, or internal issues). Proper exception handling is essential to ensure that your application remains stable and resilient.

<Warning>
  It's important to distinguish **forced** variations from **[simulated](#getvisitorcode)** variations:

  * **Forced variations**: Are specific to an individual expérience.
  * **Simulated variations**: Affect the overall **feature flag** résultat.
</Warning>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { setForcedVariation } = useFeatureFlag();

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

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

        // -- Forcing the variation "on" in the feature flag "featureKey1" for the visitor
        setForcedVariation({
          visitorCode: visitorCode,
          experimentId: 9516,
          variationKey: 'on',
          forceTargeting: false,
        });

        // -- Resetting the forced variation for the "featureKey1" feature flag for the visitor
        setForcedVariation({
          visitorCode: visitorCode,
          experimentId: 9516,
          variationKey: null,
        });
      }, [initialize, visitorCode, setForcedVariation, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { setForcedVariation } = useFeatureFlag();

      const init = useCallback(async () => {
        await initialize();

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

        // -- Forcing the variation "on" for the "featureKey1" feature flag for the visitor
        setForcedVariation({
          visitorCode: visitorCode,
          experimentId: 9516,
          variationKey: 'on',
          forceTargeting: false,
        });

        // -- Resetting the forced variation for the "featureKey1" feature flag for the visitor
        setForcedVariation({
          visitorCode: visitorCode,
          experimentId: 9516,
          variationKey: null,
        });
      }, [initialize, visitorCode, setForcedVariation, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

An object of type `SetForcedVariationParametersType` with the following properties:

| Name                      | Type      | Description                                                                                                                                       | Default                                                                                                                                                                      |   |
| ------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| visitorCode (*required*)  | `string`  | Unique identifier of le visiteur.                                                                                                                 |                                                                                                                                                                              |   |
| experienceId (*required*) | `number`  | **Expérience Id** that sera targeted and selected during the evaluation process.                                                                  |                                                                                                                                                                              |   |
| variationKey (*required*) | \`string  | null\`                                                                                                                                            | **Variation Key** corresponding to a `Variation` that devrait étre forced as the returned value for the expérience. If la valeur is `null`, the forced variation sera reset. |   |
| forceCiblage (*optional*) | `boolean` | Indicates whether ciblage for the expérience devrait étre forced and skipped (`true`) or applied as in the standard evaluation process (`false`). | `true`                                                                                                                                                                       |   |

##### Exceptions thrown

| Type                                               | Description                                                                                                                                                                                                                                         |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `KameleoonException.VisitorCodeEmpty`              | The visiteur code is empty.                                                                                                                                                                                                                         |
| `KameleoonException.VisitorCodeMaxLength`          | The visiteur code exceeded the maximum length (255 characters).                                                                                                                                                                                     |
| `KameleoonException.Initialization`                | Indicates that le SDK n'est pas yet fully initialized.                                                                                                                                                                                              |
| `KameleoonException.FeatureFlagExperimentNotFound` | Exception indicating that la requeteed expérience id has not been found in le SDK's internal configuration. This is usually normal and means that the rule's corresponding expérience has not yet been activated on Kameleoon's side.               |
| `KameleoonException.FeatureFlagVariationNotFound`  | Exception indicating that la requeteed variation key(id) has not been found in the internal configuration of le SDK. This is usually normal and means that the variation's corresponding expérience has not yet been activated on Kameleoon's side. |
| `KameleoonException.StorageRead`                   | Couldn't read storage données.                                                                                                                                                                                                                      |
| `KameleoonException.StorageWrite`                  | Couldn't update storage données.                                                                                                                                                                                                                    |

<Info>
  In most cases, only the basic erreur, `KameleoonException`, needs to be handled, as demonstrated in l'exemple. Cependant, if different types of erreurs require une réponse, handle each one separately basé sur specific requirements. De plus, for enhanced reliability, general language erreurs peut être handled by including `Error`.
</Info>

#### evaluateAudiences()

* 📨 *Sends Suivi Données to Kameleoon*

Cette méthode evaluates visiteurs against all available Audiences Explorer segments and tracks those who match.

`evaluateAudiences()` devrait étre called **after all relevant visiteur données has been set or updated**, and **just before** getting a feature variation or checking a feature flag. Thest unpproach ensures that le visiteur is evaluated against the most current données available, allowing for accurate audience assignment basé sur all criteria.

After calling cette méthode, vous pouvez perform a detailed analysis of segment performance in Audiences Explorer.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { evaluateAudiences } = useFeatureFlag();

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

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

        evaluateAudiences(visitorCode);
      }, [initialize, visitorCode, evaluateAudiences, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { evaluateAudiences } = useFeatureFlag();

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

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

        evaluateAudiences(visitorCode);
      }, [initialize, visitorCode, evaluateAudiences, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                     | Type     | Description                       |
| ------------------------ | -------- | --------------------------------- |
| visitorCode (*required*) | `string` | Unique identifier of le visiteur. |

##### Exceptions thrown

| Type                                      | Description                                                                                        |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | Method was executed before the `kameleoonClient` completed c'est [`initialize`](#initialize) call. |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty.                                                                        |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters).                                    |

<Info>
  In most cases, only the basic erreur, `KameleoonException`, needs to be handled, as demonstrated in l'exemple. Cependant, if different types of erreurs require une réponse, handle each one separately basé sur specific requirements. De plus, for enhanced reliability, general language erreurs peut être handled by including `Error`.
</Info>

#### getDataFichier()

<Tip>
  To evaluate all feature flags, use [`getVariations()`](#getvariations). Cette méthode is more efficient than calling `DataFile` and iterating through flags with [`getVariation()`](#getvariation).
</Tip>

Renvoie le current SDK configuration as a [`DataFile`](#donneesfichier) object.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useFeatureFlag,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { getDataFile } = useFeatureFlag();

      useEffect(() => {
        const dataFile = getDataFile();
      }, [getDataFile]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsч theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useFeatureFlag,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { getDataFile } = useFeatureFlag();

      useEffect(() => {
        const dataFile = getDataFile();
      }, [getDataFile]);
    }
    ```
  </Tab>
</Tabs>

##### Valeur de retour

| Type       | Description                                                       |
| ---------- | ----------------------------------------------------------------- |
| `DataFile` | The [`DataFile`](#donneesfichier) containing le SDK configuration |

### Visiteur données

This section provides la méthodes you use to manage visiteur données.

#### getVisitorCode()

`getVisitorCode` method collected from `useVisitorCode` hook obtains a visiteur code from the browser cookie. If le visiteur code n'existe pas yet, la fonction generates a random visiteur code (or uses the `defaultVisitorCode` value if you provided one) and sets the new visiteur code in a cookie.

<Info>
  The `getVisitorCode()` method allows you to set **simulated** variations for a visiteur. When cookies (from a **request** or **document**) contain la clé `kameleoonSimulationFFData`, the standard evaluation process is bypassed. Instead, la méthode directly renvoie un [`Variation`](#variation) basé sur the provided données.

  Vous pouvez apply simulations in two ways:

  * **Automatically (recommended):** If using Kameleoon Web Experienceation or le SDK in [Hybrid mode](/developer-docs/feature-experimentation/get-started/hybrid-experimentation#linking-feature-expériences-with-front-end-suivi-code), the cookie is created automatically when simulating a variant's display en utilisant la fonction [Simulation Panel](/user-manual/experimentation/feature-experimentation/using-the-rollout-planner/validation-and-rollback/using-simulation-mode).
  * **Manually:** Set the `kameleoonSimulationFFData` cookie manually.

  It's important to distinguish **simulated** variations from **[forced](#setforcedvariation)** variations:

  * **Simulated variations**: Affect the overall **feature flag** résultat.
  * **Forced variations**: Are specific to an individual expérience.

  ⚙️ **Manual setup**

  Please ensure the `kameleoonSimulationFFData` cookie follows this format:

  * `kameleoonSimulationFFData={"featureKey":{"expId":10,"varId":20}}`: Simulates the variation with `varId` of expérience `expId` for the given `featureKey`.
  * `kameleoonSimulationFFData={"featureKey":{"expId":0}}`: Simulates the default variation (defined in the **Then, for everyone else in Production, serve** section) for the given `featureKey`.

  ⚠️ To ensure proper functionality, the cookie value doit étre encoded as a URI component using une méthode tel que [`encodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent).
</Info>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useVisitorCode } from '@kameleoon/react-sdk';

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

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

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

        // -- Pass, save, and retrieve the default visitorCode.
        const visitorCode = getVisitorCode('default_visitor_code');
      }, [initialize, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useVisitorCode } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();

      const init = useCallback(async () => {
        await initialize();

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

        // -- Pass, save, and retrieve the default visitorCode.
        const visitorCode = getVisitorCode('default_visitor_code');
      }, [initialize, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                            | Type     | Description                                                              |
| ------------------------------- | -------- | ------------------------------------------------------------------------ |
| defaultVisitorCode (*optional*) | `string` | visiteur code to be utilisé dans case il y a no visiteur code in cookies |

<Note>
  If you don't provide a `defaultVisitorCode` and il y a no visiteur code stored in a cookie, le visiteur code sera randomly generated.
</Note>

##### Valeur de retour

| Type     | Description             |
| -------- | ----------------------- |
| `string` | résultat visiteur code. |

##### Exceptions thrown

| Type                                      | Description                           |
| ----------------------------------------- | ------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code length was exceeded |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty            |

***

#### addData()

The `addData` function, used with the `useData` hook, collects ciblage données to store for other hooks to determine if the current visiteur is targeted.

<Note>
  * The `addData()` function ne fait pas return any value and ne fait pas interact with Kameleoon back-end servers on its own. Instead, all the declared données is saved for future transmission via the [flush](#flush) method .Thest unpproach helps reduce the number of server calls made, as les données is typically grouped into a single server call triggered by the execution of [flush](#flush).

  The [trackConversion](#trackconversion) method also sends out any previously associated données, just like the [flush](#flush). The same holds true for [getFeatureFlagVariationKey](#getfeatureflagvariationkey) and [getFeatureVariable](#getfeatureflagvariable) methods if an experimentation rule is triggered.

  * `userAgent` données will not be stored in storage like other données, and it sera sent with every suivi request for bot filtration.

  * Check la liste des [supported conditions](#ciblage-conditions) to know what données types peut être utilisé pour ciblage
</Note>

<Tip>
  Each visiteur can only have one instance de associated données for most données types. Cependant, `CustomData` est un exception. Visiteurs can have one instance de associated `CustomData` per `customDataIndex`.
</Tip>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useVisitorCode,
      useData,
      CustomData,
      Browser,
      BrowserType,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { addData } = useData();

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

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

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

        // -- Add a single data item (tracked by default)
        addData('my_visitor_code', browserData);

        // -- Add multiple data items (tracked by default)
        addData('my_visitor_code', browserData, customData);

        // -- Add multiple data items from array (tracked by default)
        const dataArr = [browserData, customData];
        addData('my_visitor_code', ...dataArr);

        // -- Add multiple data items stored locally for targeting only (not sent to the Kameleoon Data API)
        addData({visitorCode: 'my_visitor_code', track: false, data: dataArr});
      }, [initialize, visitorCode, addData, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useVisitorCode,
      useData,
      CustomData,
      Browser,
      BrowserType,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

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

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

        // -- Add a single data item (tracked by default)
        addData('my_visitor_code', browserData);

        // -- Add multiple data items (tracked by default)
        addData('my_visitor_code', browserData, customData);

        // -- Add multiple data items from array (tracked by default)
        const dataArr = [browserData, customData];
        addData('my_visitor_code', ...dataArr);

        // -- Add multiple data items stored locally for targeting only (not sent to the Kameleoon Data API)
        addData({visitorCode: 'my_visitor_code', track: false, data: dataArr});
      }, [initialize, visitorCode, addData, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                          | Type                  | Description                                                                                                                                                                                         | Valeur par défaut |
| ----------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| visitorCode (*required*)      | `string`              | unique visiteur identification string, can't exceed 255 characters.                                                                                                                                 |                   |
| track (*optional*)            | `boolean`             | Specifies whether the added données is eligible for suivi. When set to `false`, les données is stored locally and used only for ciblage evaluation; it n'est pas sent to the Kameleoon Données API. | `true`            |
| kameleoonDonnees (*optional*) | `KameleoonDataType[]` | number of instances de any type of `KameleoonData`, peut être added solely in array or as sequential arguments                                                                                      |                   |

<Note>
  * `kameleoonData` is variadic argument it peut être passé en tant que one or several arguments (see l'exemple)

  * The index or ID of the [données personnalisées](/user-manual/assets/custom-data/create-custom-data) peut être found in your Kameleoon account. C'est important to notez que this index starts at `0`, which means that the first données personnalisées you create for a given site sera assigned `0` as its ID, not `1`.
</Note>

##### Exceptions thrown

| Type                                      | Description                                                                        |
| ----------------------------------------- | ---------------------------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters)                     |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                                         |
| `KameleoonException.StorageWrite`         | Couldn't update storage données                                                    |
| `KameleoonException.Initialization`       | Method was executed before the `kameleoonClient` completed c'est `initialize` call |

<Note>
  Consultez la section [Données types](#données-types) référence pour plus de détails of how to manage different données types.
</Note>

***

#### flush()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    Method `flush` collected with `useData` takes the Kameleoon données associated with le visiteur and sends les données suivi request along with all of les données that's been added previously en utilisant la fonction [addData](#adddata).

    If you don't specify a `visitorCode`, le SDK flushes all of its stored données to the remote Kameleoon servers. If any previously failed suivi requests were stored locally during [offline mode](#initialize), le SDK attempts to send the stored requests before executing the latest request.

    <Note>
      The `isUniqueIdentifier` parameter peut être useful in some edge-case scenarios, tel que lorsque vous can't access the anonymous `visitorCode` that was originally assigned to le visiteur, but you do have access to an internal ID that is connected to the anonymous visiteur using session merging capabilities.
    </Note>

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useVisitorCode,
          useData,
          CustomData,
        } from '@kameleoon/react-sdk';

        function MyComponent(): JSX.Element {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { addData, flush } = useData();

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

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

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

            // -- Flush added custom data for visitor
            flush(visitorCode);

            // -- Instantly flush added custom data for visitor (fire-and-forget)
            flushInstant(visitorCode);

            // -- Instantly flush added custom data for visitor and wait for completion
            await flushInstant(visitorCode);

            // -- Flush data for all the visitors
            flush();

            // -- Instantly flush data for all the visitors (fire-and-forget)
            flushInstant();

            // -- Instantly flush data for all the visitors and wait for complention
            await flushInstant();

            // -- Flush data with unique visitor identifier flag
            const internalUserId = 'my_user_id';
            flush(internalUserId, true);
          }, [initialize, visitorCode, addData, flush, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useVisitorCode,
          useData,
          CustomData,
        } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { addData, flush } = useData();

          const init = useCallback(async () => {
            await initialize();

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

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

            // -- Flush added custom data for visitor
            flush(visitorCode);

            // -- Flush data for all the visitors
            flush();

            // -- Flush data with unique visitor identifier flag
            const internalUserId = 'my_user_id';
            flush(internalUserId, true);
          }, [initialize, visitorCode, addData, flush, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Arguments

    | Name                            | Type      | Description                                                                                                                                                  | Default |
    | ------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
    | visitorCode (*optional*)        | `string`  | unique visiteur identification string, can't exceed 255 characters length, if not passed all les données sera flushed (sent to the remote Kameleoon servers) | -       |
    | isUniqueIdentifier (*optional*) | `boolean` | une optional parameter for specifying if le visitorCode est un unique identifier                                                                             | `false` |

    ##### Exceptions thrown

    | Type                                      | Description                                                                        |
    | ----------------------------------------- | ---------------------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters)                     |
    | `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                                         |
    | `KameleoonException.Initialization`       | Method was executed before the `kameleoonClient` completed c'est `initialize` call |
  </Tab>

  <Tab title="SDK Version 10">
    `flush()` takes the Kameleoon données associated with le visiteur and schedules les données to be sent with the next suivi request. The time of the next suivi request is defined by SDK Configuration [`trackingInterval`](#configuration-parameters) parameter. Visiteur données peut être added using [addData](#adddata) and [getRemoteVisiteurDonnees](#getremotevisiteurdonnees) methods.

    If you don't specify a `visitorCode`, le SDK flushes all of its stored données to the remote Kameleoon servers. If any previously failed suivi requests were stored locally during [offline mode](#initialize), le SDK attempts to send the stored requests before executing the latest request.

    <Tip>
      Si vous avez besoin de send suivi requests immediately, use `flushInstant()` — the asynchronous version of `flush` that renvoie `Promise<void>`. Vous pouvez `await` it lorsque vous need delivery guarantees (par exemple, before page navigation/unload), or call it without `await` as a fire-and-forget request:

      * `await flushInstant(visitorCode)` sends suivi requests immediately for a specific visiteur and waits for completion
      * `await flushInstant()` sends suivi requests immediately for all visiteurs and waits for completion
    </Tip>

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useVisitorCode,
          useData,
          CustomData,
        } from '@kameleoon/react-sdk';

        function MyComponent(): JSX.Element {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { addData, flush } = useData();

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

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

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

            // -- Flush added custom data for visitor
            flush(visitorCode);

            // -- Instantly flush added custom data for visitor
            flush({ visitorCode, instant: true });

            // -- Flush data for all the visitors
            flush();

            // -- Instantly flush data for all the visitors
            flush({ instant: true });
          }, [initialize, visitorCode, addData, flush, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          useVisitorCode,
          useData,
          CustomData,
        } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { addData, flush } = useData();

          const init = useCallback(async () => {
            await initialize();

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

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

            // -- Flush added custom data for visitor
            flush(visitorCode);

            // -- Instantly flush added custom data for visitor
            flush({ visitorCode, instant: true });

            // -- Flush data for all the visitors
            flush();

            // -- Instantly flush data for all the visitors
            flush({ instant: true });
          }, [initialize, visitorCode, addData, flush, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Arguments

    | Name                     | Type     | Description                                                                                                                                         | Default |
    | ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
    | visitorCode (*optional*) | `string` | unique visiteur identification string, can't exceed 255 characters, if not passed, all données sera flushed (sent to the remote Kameleoon servers). | -       |

    Or an object with the type FlushParamsType, containing:

    | Name                     | Type      | Description                                                                                                                                         | Default |
    | ------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
    | visitorCode (*optional*) | `string`  | unique visiteur identification string, can't exceed 255 characters, if not passed, all données sera flushed (sent to the remote Kameleoon servers). | -       |
    | instant (*optional*)     | `boolean` | Boolean flag indicating whether les données devrait étre sent instantly (`true`) or according to the scheduled suivi interval (`false`).            | -       |

    ##### Exceptions thrown

    | Type                                      | Description                                                                        |
    | ----------------------------------------- | ---------------------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters)                     |
    | `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                                         |
    | `KameleoonException.Initialization`       | Method was executed before the `kameleoonClient` completed c'est `initialize` call |
  </Tab>
</Tabs>

***

#### getRemoteDonnees()

Asynchronous method `getRemoteData`, collected with the `useData` hook, renvoie un données stored for specified site code on a remote Kameleoon server.

Par exemple, vous pouvez utiliser cette fonction to retrieve utilisateur preferences, historical données, or any other données relevant to your application's logic. By storing this données on our highly scalable servers using our \[Données API], vous pouvez efficiently manage massive amounts of données and retrieve it for each of your visiteurs or utilisateurs.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useData } from '@kameleoon/react-sdk';

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

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

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

      useEffect(() => {
        getData();
      }, [getData]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useData } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { getRemoteData } = useData();

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

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

      useEffect(() => {
        getData();
      }, [getData]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name             | Type     | Description                                                     |
| ---------------- | -------- | --------------------------------------------------------------- |
| key (*required*) | `string` | unique key that les données you try to get est unssociated with |

##### Valeur de retour

| Type       | Description                                      |
| ---------- | ------------------------------------------------ |
| `JSONType` | promise with données retrieved for specific key. |

##### Exceptions thrown

| Type                            | Description                                     |
| ------------------------------- | ----------------------------------------------- |
| `KameleoonException.RemoteData` | Couldn't retrieve données from Kameleoon server |

***

#### getRemoteVisiteurDonnees()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    `getRemoteVisitorData()` est un asynchronous method for retrieving Kameleoon Visits Données for the `visitorCode` from the Kameleoon Données API. The method adds les données to storage for other methods to use when making ciblage decisions.

    Données obtained using cette méthode plays an important role lorsque vous want to:

    * use données collected from other devices.
    * access a utilisateur's history, tel que previously visited pages during past visits.
    * use données that is only accessible on le client-side, like donneeslayer variables and objectifs that only convert on the front-end.

    Read [cet article](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) for a better understanding of possible use cases.

    <Warning>
      Par défaut, `getRemoteVisitorData()` automatically retrieves the latest stored données personnalisées with `scope=Visitor` and attaches them to le visiteur without the need to call la méthode `addData()`. C'est particularly useful for [synchronizing données personnalisées between multiple devices](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-données-across-devices).
    </Warning>

    <Note>
      The `isUniqueIdentifier` parameter peut être useful in edge-case scenarios, tel que lorsque vous can't access the anonymous `visitorCode` that was originally assigned to le visiteur, but you do have access to an internal ID that is connected to the anonymous visiteur using session merging capabilities.
    </Note>

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useData,
          KameleoonDataType,
          VisitorDataFiltersType,
        } from '@kameleoon/react-sdk';

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

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

            // -- Get remote visitor data without adding it to storage.
            const kameleoonDataList: KameleoonDataType[] = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
            });

            // -- Get remote visitor data without adding it to storage,
            //    and customizing filters for retrieving visits data.
            const filters: VisitorDataFiltersType = {
              currentVisit: true,
              previousVisitAmount: 10,
              customData: true,
              geolocation: true,
              conversions: true,
            };

            const kameleoonDataList: KameleoonDataType[] = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
              filters,
            });
          }, [getRemoteVisitorData]);

          useEffect(() => {
            getData();
          }, [getData]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useData } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { getRemoteVisitorData } = useData();

          const getData = useCallback(async () => {
            // -- Get remote visitor data and add it to storage.
            const kameleoonDataList = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
            });

            // -- Get remote visitor data without adding it to storage.
            const kameleoonDataList = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
            });

            // -- Get remote visitor data without adding it to storage,
            //    and customizing filters for retrieving visits data.
            const filters = {
              currentVisit: true,
              previousVisitAmount: 10,
              customData: true,
              geolocation: true,
              conversions: true,
            };

            const kameleoonDataList = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
              filters,
            });
          }, [getRemoteVisitorData]);

          useEffect(() => {
            getData();
          }, [getData]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Arguments

    An object with the type `RemoteVisitorDataParamsType` containing:

    | Name                            | Type                     | Description                                                                                                                                                  | Default Value                                                                                                  |
    | ------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
    | visitorCode (*required*)        | `string`                 | unique visiteur identification string, can't exceed 255 characters length                                                                                    | -                                                                                                              |
    | shouldAddData (*optional*)      | `boolean`                | boolean flag identifying whether the retrieved données personnalisées devrait étre set to the storage like `addData` method does                             | `true`                                                                                                         |
    | filters (*optional*)            | `VisitorDataFiltersType` | filters for specifying what données devrait étre retrieved from visits, par défaut only `customData` is retrieved from the current and latest previous visit | `{ previousVisitAmount: 1, currentVisit: true customData: true }`, other filters parameters are set to `false` |
    | isUniqueIdentifier (*optional*) | `boolean`                | optional parameter that, when `true`, specifies that le visitorCode est un unique identifier                                                                 | `false`                                                                                                        |

    ##### Valeur de retour

    | Type                  | Description                                       |
    | --------------------- | ------------------------------------------------- |
    | `KameleoonDataType[]` | promise with liste de Kameleoon Données retrieved |

    ##### Exceptions thrown

    | Type                                      | Description                                                            |
    | ----------------------------------------- | ---------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters)         |
    | `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                             |
    | `KameleoonException.RemoteData`           | Couldn't retrieve données from Kameleoon server                        |
    | `KameleoonException.VisitAmount`          | Visit amount doit étre a number between 1 and 25                       |
    | `KameleoonException.Initialization`       | Method was executed before `initialize` was done for `kameleoonClient` |

    ##### Using parameters in getRemoteVisiteurDonnees()

    The `getRemoteVisitorData()` method offers flexibility by allowing you to define various parameters when retrieving données on visiteurs. Whether you're ciblage basé sur objectifs, expériences, or variations, the same approach applies across all données types.

    Par exemple, let's say you want to retrieve données on visiteurs who completed a objectif "Order transaction". Vous pouvez specify parameters within the `getRemoteVisitorData()` method to refine your ciblage. For instance, si vous voulez target only utilisateurs who converted on the objectif in their last five visits, vous pouvez définir the `previousVisitAmount` parameter to 5 and `conversions` to true.

    The flexibility shown dans cet exemple n'est pas limited to objectif données. Vous pouvez utiliser parameters within the `getRemoteVisitorData()` method to retrieve données on a variety of visiteur behaviors.

    <Note>
      Here is la liste des available `VisitorDataFiltersType` filters:

      | Name                             | Type      | Description                                                                                                                                                                             | Default |
      | -------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
      | previousVisitAmount (*optional*) | `number`  | Number of previous visits to retrieve données from. Number between `1` and `25`                                                                                                         | `1`     |
      | currentVisit (*optional*)        | `boolean` | If true, current visit données sera retrieved                                                                                                                                           | `true`  |
      | customData (*optional*)          | `boolean` | If true, données personnalisées sera retrieved.                                                                                                                                         | `true`  |
      | pageViews (*optional*)           | `boolean` | If true, page données sera retrieved.                                                                                                                                                   | `false` |
      | geolocation (*optional*)         | `boolean` | If true, geolocation données sera retrieved.                                                                                                                                            | `false` |
      | device (*optional*)              | `boolean` | If true, device données sera retrieved.                                                                                                                                                 | `false` |
      | browser (*optional*)             | `boolean` | If true, browser données sera retrieved.                                                                                                                                                | `false` |
      | operatingSystem (*optional*)     | `boolean` | If true, operating system données sera retrieved.                                                                                                                                       | `false` |
      | conversions (*optional*)         | `boolean` | If true, conversion données sera retrieved.                                                                                                                                             | `false` |
      | expériences (*optional*)         | `boolean` | If true, expérience données sera retrieved.                                                                                                                                             | `false` |
      | kcs (*optional*)                 | `boolean` | If true, Kameleoon Conversion Score (KCS) sera retrieved. Requires the [AI Predictive Ciblage add-on](/user-manual/ai-predictive-targeting/target-users-based-on-likelihood-to-convert) | `false` |
    </Note>
  </Tab>

  <Tab title="SDK Version 10">
    `getRemoteVisitorData()` est un asynchronous method for retrieving Kameleoon Visits Données for the `visitorCode` from the Kameleoon Données API. The method adds les données to storage for other methods to use when making ciblage decisions.

    Données obtained using cette méthode plays an important role lorsque vous want to:

    * use données collected from other devices.
    * access a utilisateur's history, tel que previously visited pages during past visits.
    * use données that is only accessible on le client-side, like donneeslayer variables and objectifs that only convert on the front-end.

    Read [cet article](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) for a better understanding of possible use cases.

    <Warning>
      Par défaut, `getRemoteVisitorData()` automatically retrieves the latest stored données personnalisées with `scope=Visitor` and attaches them to le visiteur without the need to call la méthode `addData()`. C'est particularly useful for [synchronizing données personnalisées between multiple devices](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-données-across-devices).
    </Warning>

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useData,
          KameleoonDataType,
          VisitorDataFiltersType,
        } from '@kameleoon/react-sdk';

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

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

            // -- Get remote visitor data without adding it to storage.
            const kameleoonDataList: KameleoonDataType[] = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
            });

            // -- Get remote visitor data without adding it to storage,
            //    and customizing filters for retrieving visits data.
            const filters: VisitorDataFiltersType = {
              currentVisit: true,
              previousVisitAmount: 10,
              customData: true,
              geolocation: true,
              conversions: true,
            };

            const kameleoonDataList: KameleoonDataType[] = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
              filters,
            });
          }, [getRemoteVisitorData]);

          useEffect(() => {
            getData();
          }, [getData]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useData } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { getRemoteVisitorData } = useData();

          const getData = useCallback(async () => {
            // -- Get remote visitor data and add it to storage.
            const kameleoonDataList = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
            });

            // -- Get remote visitor data without adding it to storage.
            const kameleoonDataList = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
            });

            // -- Get remote visitor data without adding it to storage,
            //    and customizing filters for retrieving visits data
            const filters = {
              currentVisit: true,
              previousVisitAmount: 10,
              customData: true,
              geolocation: true,
              conversions: true,
            };

            const kameleoonDataList = await getRemoteVisitorData({
              visitorCode: 'my_visitor_code',
              shouldAddData: false,
              filters,
            });
          }, [getRemoteVisitorData]);

          useEffect(() => {
            getData();
          }, [getData]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Arguments

    An object with the type `RemoteVisitorDataParamsType` containing:

    | Name                       | Type                     | Description                                                                                                                                                  | Default Value                                                                                                  |
    | -------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
    | visitorCode (*required*)   | `string`                 | unique visiteur identification string, can't exceed 255 characters length                                                                                    | -                                                                                                              |
    | shouldAddData (*optional*) | `boolean`                | boolean flag identifying whether the retrieved données personnalisées devrait étre set to the storage like `addData` method does                             | `true`                                                                                                         |
    | filters (*optional*)       | `VisitorDataFiltersType` | filters for specifying what données devrait étre retrieved from visits, par défaut only `customData` is retrieved from the current and latest previous visit | `{ previousVisitAmount: 1, currentVisit: true customData: true }`, other filters parameters are set to `false` |

    ##### Valeur de retour

    | Type                  | Description                                       |
    | --------------------- | ------------------------------------------------- |
    | `KameleoonDataType[]` | promise with liste de Kameleoon Données retrieved |

    ##### Exceptions thrown

    | Type                                      | Description                                                            |
    | ----------------------------------------- | ---------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters)         |
    | `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                             |
    | `KameleoonException.RemoteData`           | Couldn't retrieve données from Kameleoon server                        |
    | `KameleoonException.VisitAmount`          | Visit amount doit étre a number between 1 and 25                       |
    | `KameleoonException.Initialization`       | Method was executed before `initialize` was done for `kameleoonClient` |

    ##### Using parameters in getRemoteVisiteurDonnees()

    The `getRemoteVisitorData()` method offers flexibility by allowing you to define various parameters when retrieving données on visiteurs. Whether you're ciblage basé sur objectifs, expériences, or variations, the same approach applies across all données types.

    Par exemple, let's say you want to retrieve données on visiteurs who completed a objectif "Order transaction". Vous pouvez specify parameters within the `getRemoteVisitorData()` method to refine your ciblage. For instance, si vous voulez target only utilisateurs who converted on the objectif in their last five visits, vous pouvez définir the `previousVisitAmount` parameter to 5 and `conversions` to true.

    The flexibility shown dans cet exemple n'est pas limited to objectif données. Vous pouvez utiliser parameters within the `getRemoteVisitorData()` method to retrieve données on a variety of visiteur behaviors.

    <Note>
      Here is la liste des available `VisitorDataFiltersType` filters:

      | Name                             | Type      | Description                                                                                                                                                                                                                                                                                                                                     | Default |
      | -------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
      | previousVisitAmount (*optional*) | `number`  | Number of previous visits to retrieve données from. Number between `1` and `25`                                                                                                                                                                                                                                                                 | `1`     |
      | currentVisit (*optional*)        | `boolean` | If true, current visit données sera retrieved                                                                                                                                                                                                                                                                                                   | `true`  |
      | customData (*optional*)          | `boolean` | If true, données personnalisées sera retrieved.                                                                                                                                                                                                                                                                                                 | `true`  |
      | pageViews (*optional*)           | `boolean` | If true, page données sera retrieved.                                                                                                                                                                                                                                                                                                           | `false` |
      | geolocation (*optional*)         | `boolean` | If true, geolocation données sera retrieved.                                                                                                                                                                                                                                                                                                    | `false` |
      | device (*optional*)              | `boolean` | If true, device données sera retrieved.                                                                                                                                                                                                                                                                                                         | `false` |
      | browser (*optional*)             | `boolean` | If true, browser données sera retrieved.                                                                                                                                                                                                                                                                                                        | `false` |
      | operatingSystem (*optional*)     | `boolean` | If true, operating system données sera retrieved.                                                                                                                                                                                                                                                                                               | `false` |
      | conversions (*optional*)         | `boolean` | If true, conversion données sera retrieved.                                                                                                                                                                                                                                                                                                     | `false` |
      | expériences (*optional*)         | `boolean` | If true, expérience données sera retrieved.                                                                                                                                                                                                                                                                                                     | `false` |
      | kcs (*optional*)                 | `boolean` | If true, Kameleoon Conversion Score (KCS) sera retrieved. Requires the [AI Predictive Ciblage add-on](/user-manual/ai-predictive-targeting/target-users-based-on-likelihood-to-convert)                                                                                                                                                         | `false` |
      | visitorCode (*optional*)         | `boolean` | If true, Kameleoon will retrieve the `visitorCode` from the most recent visit and use it for the current visit. This is necessary si vous voulez ensure that le visiteur, identified by their `visitorCode`, always receives the same variation across visits for [Cross-device experimentation](/developer-docs/cross-device-experimentation). | `true`  |
      | personalization (*optional*)     | `boolean` | If true, personalization données sera retrieved. This est requis for the personalization condition                                                                                                                                                                                                                                              | `false` |
      | cbs (*optional*)                 | `boolean` | If true, Contextual Bandit score données sera retrieved.                                                                                                                                                                                                                                                                                        | `false` |
    </Note>
  </Tab>
</Tabs>

***

#### getVisitorWarehouseDonnees()

Asynchronous method `getVisitorWarehouseAudience` collected with `useData` hook retrieves all audience données associated with le visiteur in your données warehouse en utilisant la fonction specified `visitorCode` and `warehouseKey`. The `warehouseKey` is typically your internal utilisateur ID. The `customDataIndex` parameter corresponds to the Kameleoon données personnalisées that Kameleoon uses to target your visiteurs. Consultez the [warehouse ciblage documentation](/user-manual/integrations/data-warehouses/bigquery/use-bigquery-as-a-source-audience-targeting) for additional détails.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useData, CustomData } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { getVisitorWarehouseAudience } = useData();

      const getData = useCallback(async (): Promise<void> => {
        // -- Get visitor warehouse audience data using `warehouseKey`
        //    and add it to storage.
        const customData: CustomData = await getVisitorWarehouseAudience({
          visitorCode: 'my_visitor',
          customDataIndex: 10,
          warehouseKey: 'my_key',
        });

        // -- Get visitor warehouse audience data using `visitorCode`
        //    and add it to storage.
        const customData: CustomData = await getVisitorWarehouseAudience({
          visitorCode: 'my_visitor',
          customDataIndex: 10,
        });
      }, [getRemoteData]);

      useEffect(() => {
        getData();
      }, [getData]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useData } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { getVisitorWarehouseAudience } = useData();

      const getData = useCallback(async () => {
        // -- Get visitor warehouse audience data using `warehouseKey`
        //    and add it to storage.
        const customData = await getVisitorWarehouseAudience({
          visitorCode: 'my_visitor',
          customDataIndex: 10,
          warehouseKey: 'my_key',
        });

        // -- Get visitor warehouse audience data using `visitorCode`
        //    and add it to storage.
        const customData = await getVisitorWarehouseAudience({
          visitorCode: 'my_visitor',
          customDataIndex: 10,
        });
      }, [getRemoteData]);

      useEffect(() => {
        getData();
      }, [getData]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

Parameters object consisting of:

| Name                         | Type     | Description                                                                                                    |
| ---------------------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
| visitorCode (*required*)     | `string` | unique visiteur identification string, can't exceed 255 characters length                                      |
| customDataIndex (*required*) | `number` | number representing the index of the données personnalisées you want to use to target your Warehouse Audiences |
| warehouseKey (*optional*)    | `string` | unique key to identify the warehouse données (usually, your internal utilisateur ID)                           |

##### Valeur de retour

| Type                          | Description                                                                                           |
| ----------------------------- | ----------------------------------------------------------------------------------------------------- |
| `Promise<CustomData \| null>` | promise containing CustomData with the associated warehouse données or `null` if there was no données |

##### Exceptions thrown

| Type                                      | Description                                                    |
| ----------------------------------------- | -------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters) |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                     |
| `KameleoonException.RemoteData`           | Couldn't retrieve données from Kameleoon server                |

***

#### setLegalConsent()

Method `setLegalConsent`, collected with `useVisitorCode` hook, specifies whether le visiteur has given legal consent to use personal données. Setting the `legalConsent` parameter to `false` limits the types of données that vous pouvez include in suivi requests. This helps you adhere to legal and regulatory requirements while responsibly managing visiteur données. Vous pouvez trouver more informations on personal données in the [consent management policy](/user-manual/project-management/consent-management-policy).

<Note>
  * Consent informations is in sync between the Kameleoon Engine (application fichier engine.js) and the React SDK. This synchronization means that once consent is set on either the Engine or le SDK, c'est automatically set for both. This feature eliminates the need for manual consent handling and ensures that SDKs operate in compliance with utilisateur preferences.

  If you use Kameleoon in Hybrid mode, we recommend reading the consent section in our [Hybrid experimentation article](/developer-docs/feature-experimentation/get-started/hybrid-experimentation/#managing-consent-in-hybrid-mode)

  * When handling legal consent, c'est important to use [`getVisitorCode`](#getvisitorcode) method. De plus, `getVisitorCode` ne fait pas accept `domain` as an argument. Instead, pass it to the [`createClient`](#createclient) function.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useVisitorCode } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode, setLegalConsent } = useVisitorCode();

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

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

        setLegalConsent(visitorCode, true);
      }, [initialize, getVisitorCode, setLegalConsent]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useVisitorCode } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode, setLegalConsent } = useVisitorCode();

      const init = useCallback(async () => {
        await initialize();

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

        setLegalConsent(visitorCode, true);
      }, [initialize, getVisitorCode, setLegalConsent]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                     | Type      | Description                                                                                                                                                                                    |
| ------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string`  | unique visiteur identification string, can't exceed 255 characters length                                                                                                                      |
| consent (*required*)     | `boolean` | a boolean value representing the legal consent status. `true` indicates le visiteur has given legal consent, `false` indicates le visiteur has never provided, or has withdrawn, legal consent |

##### Exceptions thrown

| Type                                      | Description                                                           |
| ----------------------------------------- | --------------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code length exceeded the maximum length (255 characters) |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                            |

##### Consent revocation behavior

Lorsque vous call `setLegalConsent()` with `consent=false`, le SDK ne fait pas delete the `kameleoonVisitorCode` cookie. Instead, it stops extending the cookie's expiration date, allowing the cookie to persist until it naturally expires.

If your compliance requirements demand the immediate removal of the cookie fichier upon opt-out, vous devez delete it manually using your framework's native cookie management methods. The SDK will not remove le fichier automatically.

***

### Objectifs and third-party analytics

This section provides la méthodes you use to track when a visiteur action achieve one of you objectifs (a conversion).

#### trackConversion()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    * \_📨 *Sends Suivi Données to Kameleoon*

    The `trackConversion()` function, used with the `useData` hook creates and adds [`Conversion`](#conversion) données to le visiteur with specified parameters and executes `flush()`.

    Use cette méthode to track a conversion for a specific [objectif](/user-manual/assets/goals/create-a-goal) and utilisateur. Cette méthode requires `visitorCode` and `goalId`. En plus, cette méthode also accepts une optional `revenue` argument. The `visitorCode` is usually identical to the one that was used when triggering the expérience.

    The `trackConversion()` method ne return any value. Cette méthode is non-blocking as the server call is made asynchronously.

    If you specify a `visitorCode` and set `isUniqueIdentifier` to `true`, the `trackConversion()` method uses it as the unique visiteur identifier, qui est useful for [cross-device experimentation](#cross-device-experimentation) because le SDK links the flushed données with le visiteur that est unssociated with the specified identifier.

    <Note>
      The `isUniqueIdentifier` can also be useful in other edge-case scenarios, tel que lorsque vous can't access the anonymous `visitorCode` that was originally assigned to le visiteur, but you do have access to an internal ID that is connected to the anonymous visiteur using session merging capabilities.
    </Note>

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useInitialize, useVisitorCode, useData } from '@kameleoon/react-sdk';

        function MyComponent(): JSX.Element {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { trackConversion } = useData();

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

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

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

            // -- Track conversion with unique visitor identifier flag
            const internalUserId = 'my_user_id';
            trackConversion({
              visitorCode: internalUserId,
              revenue: 20000,
              goalId: 123,
              isUniqueIdentifier: true,
            });
          }, [initialize, trackConversion, visitorCode, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useInitialize, useVisitorCode, useData } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { trackConversion } = useData();

          const init = useCallback(async () => {
            await initialize();

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

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

            // -- Track conversion with unique visitor identifier flag
            const internalUserId = 'my_user_id';
            trackConversion({
              visitorCode: internalUserId,
              revenue: 20000,
              goalId: 123,
              isUniqueIdentifier: true,
            });
          }, [initialize, trackConversion, visitorCode, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Arguments

    Parameters object consisting of:

    | Name                            | Type      | Description                                                                      | Default |
    | ------------------------------- | --------- | -------------------------------------------------------------------------------- | ------- |
    | visitorCode (*required*)        | `string`  | Unique identifier of le visiteur.                                                |         |
    | goalId (*required*)             | `number`  | ID of the objectif.                                                              |         |
    | revenue (*optional*)            | `number`  | Revenue of the conversion.                                                       | `0`     |
    | isUniqueIdentifier (*optional*) | `boolean` | An optional parameter for specifying if le visitorCode est un unique identifier. | `false` |

    ##### Exceptions thrown

    | Type                                      | Description                                                     |
    | ----------------------------------------- | --------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters). |
    | `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty.                                     |
    | `KameleoonException.StorageWrite`         | Couldn't update storage données.                                |
  </Tab>

  <Tab title="SDK Version 10">
    * 📨 *Sends Suivi Données to Kameleoon*

    The `trackConversion()` function, used with the `useData` hook creates and adds [`Conversion`](#conversion) données to le visiteur with specified parameters and executes `flush()`.

    Use cette méthode to track a conversion for a specific [objectif](/user-manual/assets/goals/create-a-goal) and utilisateur. Cette méthode requires `visitorCode` and `goalId`. En plus, cette méthode also accepts une optional `revenue`, `negative` and `metadata` arguments. The `visitorCode` is usually identical to the one that was used when triggering the expérience.

    The `trackConversion()` method ne return any value. Cette méthode is non-blocking as the server call is made asynchronously.

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useInitialize, useVisitorCode, useData, CustomData } from '@kameleoon/react-sdk';

        function MyComponent(): JSX.Element {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { trackConversion } = useData();

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

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

            // -- Track conversion
            trackConversion({
              visitorCode,
              revenue: 2000,
              goalId: 123,
              metadata: [new CustomData(0, 'value')],
              negative: true,
            });
          }, [initialize, trackConversion, visitorCode, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useInitialize, useVisitorCode, useData, CustomData } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { initialize } = useInitialize();
          const { getVisitorCode } = useVisitorCode();
          const { trackConversion } = useData();

          const init = useCallback(async () => {
            await initialize();

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

            // -- Track conversion
            trackConversion({
              visitorCode,
              revenue: 2000,
              goalId: 123,
              metadata: [new CustomData(0, 'value')],
              negative: true,
            });
          }, [initialize, trackConversion, visitorCode, getVisitorCode]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>

    ##### Arguments

    Parameters object consisting of:

    | Name                     | Type           | Description                                                                                                                            | Default     |
    | ------------------------ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
    | visitorCode (*required*) | `string`       | Unique identifier of le visiteur.                                                                                                      |             |
    | goalId (*required*)      | `number`       | ID of the objectif.                                                                                                                    |             |
    | negative (*optional*)    | `boolean`      | Defines if the revenue is positive or negative.                                                                                        | `false`     |
    | revenue (*optional*)     | `number`       | Revenue of the conversion.                                                                                                             | `0`         |
    | metadata (*optional*)    | `CustomData[]` | Metadata of the conversion. [Must be defined beforehand in the Kameleoon App](/fr/user-manual/assets/goals/create-a-goal#métadonnées). | `undefined` |

    <Note>
      Les valeurs de métadonnées sont accessibles via les [exports de données brutes](/user-manual/experiment-analytics/analyze-results/results-page/results-page-actions#Export) et la [page de résultats](/user-manual/experiment-analytics/analyze-results/data-and-metrics/goal-metadata).

      Si le paramètre `metadata` est fourni, Kameleoon utilisera les valeurs spécifiées pour la conversion actuelle au lieu de celles précédemment collectées via la méthode [`addData()`](#adddata). Si le paramètre est omis, Kameleoon utilisera les dernières valeurs suivies pour ces [`CustomData`](#customdata) avant la conversion et au cours de la même visite.

      Kameleoon ne prendra en compte que les valeurs de métadonnées explicitement passées en paramètres à la méthode `trackConversion()`.

      Dans l'exemple ci-dessous, Kameleoon associera la conversion uniquement à la valeur de données personnalisées explicitement fournie en paramètre (ici : index 5 avec la valeur 'Amex Credit Card').

      <Tabs defaultTabIndex={0}>
        <Tab title="TypeScript">
          ```ts theme={null}
          addData(visitorCode, new CustomData(5, 'Credit Card'), new CustomData(9, 'Express Delivery'));
          trackConversion({
              visitorCode,
              goalId: 1000,
              metadata: [new CustomData(5, 'Amex Credit Card')]
          });
          ```
        </Tab>

        <Tab title="JavaScript">
          ```js theme={null}
          addData(visitorCode, new CustomData(5, 'Credit Card'), new CustomData(9, 'Express Delivery'));
          trackConversion({
              visitorCode,
              goalId: 1000,
              metadata: [new CustomData(5, 'Amex Credit Card')]
          });
          ```
        </Tab>
      </Tabs>
    </Note>

    ##### Exceptions thrown

    | Type                                      | Description                                                     |
    | ----------------------------------------- | --------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters). |
    | `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty.                                     |
    | `KameleoonException.StorageWrite`         | Couldn't update storage données.                                |
  </Tab>
</Tabs>

***

#### getEngineSuiviCode()

Kameleoon integrates with several analytics solutions, including Mixpanel, Google Analytics 4, and Segment. To track server-side expériences correctly, call the `getEngineTrackingCode()` method after le visiteur triggers an expérience. The SDK renvoie JavaScript queue commands for the expériences that le visiteur triggered during the previous five seconds. Lorsque vous insert this code into the page, Engine.js processes the commands and sends the exposure événements through the active analytics intégration.

Consultez [hybrid experimentation](/developer-docs/feature-experimentation/get-started/hybrid-experimentation) pour plus d'informationss on implementing cette méthode.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useFeatureFlag } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getEngineTrackingCode, getVariation } =
        useFeatureFlag();

      const [engineCode, setEngineCode] = useState<string>('');

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

        // -- Trigger feature experiment
        // -- E.g., result `variationKey` id is `200` and implicit experiment id is `100`
        getVariation({ visitorCode: 'visitor_code', featureKey: 'my_feature_key' });

        // -- Get tracking code and set it to state
        setEngineCode(getEngineTrackingCode('visitor_code'));

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

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

      useEffect(() => {
        if (!engineCode) {
          return;
        }

        // -- Insert tracking code into the page
        const script = document.createElement('script');
        script.textContent = engineCode;

        document.body.appendChild(script);

        // -- Remove script from the page
        return () => {
          document.body.removeChild(script);
        };
      }, [engineCode]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useFeatureFlag } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getEngineTrackingCode, getVariation } =
        useFeatureFlag();

      const [engineCode, setEngineCode] = useState('');

      const init = useCallback(async () => {
        await initialize();

        // -- Trigger feature experiment
        // -- E.g., result `variationKey` id is `200` and implicit experiment id is `100`
        getVariation({ visitorCode: 'visitor_code', featureKey: 'my_feature_key' });

        // -- Get tracking code and set it to state
        setEngineCode(getEngineTrackingCode('visitor_code'));

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

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

      useEffect(() => {
        if (!engineCode) {
          return;
        }

        // -- Insert tracking code into the page
        const script = document.createElement('script');
        script.textContent = engineCode;

        document.body.appendChild(script);

        // -- Remove script from the page
        return () => {
          document.body.removeChild(script);
        };
      }, [engineCode]);
    }
    ```
  </Tab>
</Tabs>

<Note>
  * To use this feature, implement both the React SDK and Kameleoon [Engine.js](/developer-docs/web-experimentation/implementation-and-deployment/standard-implementation). Because Engine.js is used only for suivi in this flow, vous pouvez install the asynchronous tag before the closing `</body>` tag.

  * Vous pouvez insert the returned suivi code directly into an HTML `<script>` tag.

  ```html theme={null}
  <html lang="en">
    <body>
      <script>
        const engineTrackingCode = `
          window.kameleoonQueue = window.kameleoonQueue || [];
          window.kameleoonQueue.push(['Experiments.assignVariation', 123456, 7890, true]);
          window.kameleoonQueue.push(['Experiments.trigger', 123456, true]);
          window.kameleoonQueue.push(['Experiments.assignVariation', 234567, 8901, true]);
          window.kameleoonQueue.push(['Experiments.trigger', 234567, true]);
        `;
        const script = document.createElement('script');

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

    </body>
  </html>
  ```

  Dans cet exemple, `123456` and `234567` are expérience IDs, and `7890` and `8901` are variation IDs. In your implementation, le SDK generates these values in the returned suivi code.
</Note>

##### Arguments

| Name                     | Type     | Description                       |
| ------------------------ | -------- | --------------------------------- |
| visitorCode (*required*) | `string` | Unique identifier of le visiteur. |

##### Valeur de retour

| Type     | Description                              |
| -------- | ---------------------------------------- |
| `string` | JavaScript code to insert into the page. |

##### Exceptions thrown

| Type                                      | Description                                                    |
| ----------------------------------------- | -------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters) |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                     |

***

### Événements

This section provides la méthodes you use to handle événements.

<Tabs defaultTabIndex={0}>
  <Tab title="SDK Version 10">
    #### onEvenement()

    Method `onEvent`, collected with the `useInitialize` hook, fires a callback when a specific événement is triggered. The callback function has access to les données associated with the événement. The SDK methods in this documentation note which événement types they can trigger, if any.

    <Tabs defaultTabIndex={0}>
      <Tab title="TypeScript">
        ```tsx theme={null}
        import { useEffect, useCallback } from 'react';
        import {
          useInitialize,
          EventType,
          EvaluationEventDataType,
        } from '@kameleoon/react-sdk';

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

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

            // -- Define logic to execute on SDK event
            onEvent(EventType.Evaluation, (eventData: EventDataType) => {
              // -- My Logic
            });
          }, [initialize, onEvent]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>

      <Tab title="JavaScript">
        ```jsx theme={null}
        import { useEffect, useCallback } from 'react';
        import { useInitialize, EventType } from '@kameleoon/react-sdk';

        function MyComponent() {
          const { initialize, onEvent } = useInitialize();

          const init = useCallback(async () => {
            await initialize();

          // -- Define logic to execute on SDK event
          .onEvent(EventType.Evaluation, (eventData) => {
            // -- My Logic
          });
          }, [initialize, onEvent]);

          useEffect(() => {
            init();
          }, [init]);
        }
        ```
      </Tab>
    </Tabs>

    <Note>
      Vous pouvez only assign one callback to each `EventType`.
    </Note>

    ##### Événements

    Événements are defined in the `EventType` enum. Depending on the événement type, the `eventData` parameter will have a different type.

    | Type                            | `eventData` type                   | Description                                                                                                             |
    | ------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
    | `EventType.Evaluation`          | `EvaluationEventDataType`          | Triggered when le SDK evaluates any variation for a feature flag. C'est triggered regardless of le resultatat variation |
    | `EventType.ConfigurationUpdate` | `ConfigurationUpdateEventDataType` | Triggered when le SDK receives a configuration update from the server (when using real-time streaming)                  |

    ##### Arguments

    | Name                   | Type                                            | Description                                                                                               |
    | ---------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
    | événement (*required*) | `EventType`                                     | a type of the événement to associate the callback action with                                             |
    | callback (*required*)  | `(eventData: EventDataType<EventType>) => void` | a callback function with the `eventData` parameter that sera appelé lorsque a configuration update occurs |

    ##### Exceptions thrown

    | Type                                | Description                                                                        |
    | ----------------------------------- | ---------------------------------------------------------------------------------- |
    | `KameleoonException.Initialization` | Method was executed before the `kameleoonClient` completed c'est `initialize` call |

    ***

    ##### Sending exposure événements to external tools

    Kameleoon offers built-in integrations with various analytics and CDP solutions, tel que [Mixpanel, Google Analytics 4, Segment...](/user-manual/integrations/integrations-overview). To ensure that vous pouvez track and analyze your server-side expériences, Kameleoon provides une méthode `getEngineTrackingCode()` that renvoie le JavasScript code to be inserted in your page to automatically send the exposure événements to the analytics solution you are using. The SDK builds a suivi code for your active analytics solution basé sur the expériences that le visiteur has triggered in the last 5 seconds.
    Pour plus d'informationss about hybrid experimentation, please consultez this [documentation](/developer-docs/feature-experimentation/get-started/hybrid-experimentation).

    <Note>
      To benefit from this feature, vous allez need to implement both the React SDK and our Kameleoon JavaScript tag. We recommend you implement the \[Kameleoon asynchronous tag], which vous pouvez install before your closing `<body>` tag in your HTML page, as it sera only utilisé pour suivi purposes.
    </Note>
  </Tab>
</Tabs>

### Données types

Kameleoon Données types are helper classes utilisé pour storing données in storage in predefined forms.
During the [flush](#flush) execution, le SDK collects all les données and sends it along with the suivi request.

Données available in le SDK n'est pas available for ciblage and reporting in the Kameleoon app until you add les données. Par exemple, by en utilisant la fonction `addData()` method.
See [use visit history to target utilisateurs](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) pour plus d'informationss.

<Note>
  Si vous êtes using hybrid mode, vous pouvez appeler `getRemoteVisitorData()` to automatically fill all données that Kameleoon has collected previously.
</Note>

#### Browser

<Note>
  Since React SDK `10.11.0`, `Browser` est unutomatically detected basé sur the `User-Agent` string. Cependant, vous pouvez still manually override it if needed.
</Note>

Browser contains browser informations.

<Note>
  Each visiteur can only have one `Browser`. Adding a second `Browser` overwrites the first one.
</Note>

| Name                 | Type          | Description                                                                                     |
| -------------------- | ------------- | ----------------------------------------------------------------------------------------------- |
| browser (*required*) | `BrowserType` | predefined browser type (`Chrome`, `InternetExplorer`, `Firefox`, `Safari`, `Opera`, `Other`)   |
| version (*optional*) | `number`      | version of the browser, floating point number represents major and minor version of the browser |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      Browser,
      BrowserType,
    } from '@kameleoon/react-sdk';

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

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      Browser,
      BrowserType,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

#### UniqueIdentifier

`UniqueIdentifier` données is used as marker for unique visiteur identification.

If you add `UniqueIdentifier` for a visiteur, `visitorCode` is used as the unique visiteur identifier, qui est useful for [Cross-device experimentation](/developer-docs/cross-device-experimentation). Associating a `UniqueIdentifier` with a visiteur notify SDK that le visiteur is linked to another visiteur.

The `UniqueIdentifier` can also be useful in other edge-case scenarios, tel que lorsque vous can't access the anonymous `visitorCode` that was originally assigned to le visiteur, but you do have access to an internal ID that is connected to the anonymous visiteur using session merging capabilities.

<Note>
  Each visiteur can only have one `UniqueIdentifier`. Adding another `UniqueIdentifier` overwrites the first one.
</Note>

| Name               | Type      | Description                                                                                                                                                          |
| ------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| value (*required*) | `boolean` | value that specifies if le visiteur est unssociated with another visiteur, provided `false` will imply that le visiteur n'est pas associated with any other visiteur |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, UniqueIdentifier } from '@kameleoon/react-sdk';

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

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

        // -- Add new unique identifier to a visitor
        addData('my_visitor_code', new UniqueIdentifier(true));
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, UniqueIdentifier } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Add new unique identifier to a visitor
        addData('my_visitor_code', new UniqueIdentifier(true));
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

#### Conversion

The `Conversion` données set stored here peut être utilisé pour filter expérience and personalization reports by any objectif associated with it.

<Tip>
  * Each visiteur can have multiple `Conversion` objects.
  * Vous pouvez trouver the `goalId` in the Kameleoon app.
</Tip>

`ConversionParametersType` conversionParameters - an object with conversion parameters described below

| Name                  | Type           | Description                                     | Default     |
| --------------------- | -------------- | ----------------------------------------------- | ----------- |
| goalId (*required*)   | `number`       | ID of the objectif.                             |             |
| revenue (*optional*)  | `float`        | Revenue of the conversion                       | `0`         |
| negative (*optional*) | `boolean`      | Defines if the revenue is positive or negative. | `false`     |
| metadata (*optional*) | `CustomData[]` | Metadata of the conversion.                     | `undefined` |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      Conversion,
      ConversionParametersType,
      CustomData,
    } from '@kameleoon/react-sdk';

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

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

        // -- Defined conversion parameters
        const conversionParameters: ConversionParametersType = {
          goalId: 123,
          revenue: 10000,
          negative: true,
          metadata: [new CustomData(0, 'value')],
        };

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, Conversion, CustomData } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Defined conversion parameters
        const conversionParameters = {
          goalId: 123,
          revenue: 10000,
          negative: true,
          metadata: [new CustomData(0, 'value')],
        };

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

#### Cookie

`Cookie` contains informations about the cookie stored on du visiteur device.

<Note>
  * Generally, the React SDK will attempt to use a `localStorage` cookie for the conditions. If not possible, SDK can use `Cookie` données as an alternative.

  * Each visiteur can only have one `Cookie`. Adding a second `Cookie` overwrites the first one.
</Note>

| Name                | Type           | Description                                                          |
| ------------------- | -------------- | -------------------------------------------------------------------- |
| cookie (*required*) | `CookieType[]` | A liste de `CookieType` objects consisting of cookie keys and values |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import {
      KameleoonClient,
      CookieType,
      Cookie,
      useInitialize,
      useData,
    } from '@kameleoon/react-sdk';

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

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

        // -- Add new cookie data to client
        const cookieData: CookieType[] = [
          { key: 'key_1', value: 'value_1' },
          { key: 'key_2', value: 'value_2' },
        ];
        const cookie = new Cookie(cookieData);
        addData('my_visitor_code', cookie);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import {
      KameleoonClient,
      CookieType,
      Cookie,
      useInitialize,
      useData,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Add new cookie data to client
        const cookieData = [
          { key: 'key_1', value: 'value_1' },
          { key: 'key_2', value: 'value_2' },
        ];
        const cookie = new Cookie(cookieData);
        addData('my_visitor_code', cookie);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Méthodes

`Cookie` données has a static utility method `fromString` that vous pouvez utiliser to create a cookie instantly by parsing a string that contains valid cookie données.
The method accepts `string` as parameter and renvoie un initialized `Cookie` instance.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { Cookie } from '@kameleoon/react-sdk';

    const cookieString = 'key_1=value_1; key_2=value_2';
    const cookie: Cookie = Cookie.fromString(cookieString);

    // -- The result cookie will contain the following cookie array
    // [
    //    { key: 'key_1', value: 'value_1' },
    //    { key: 'key_2', value: 'value_2' },
    // ]
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import { Cookie } from '@kameleoon/react-sdk';

    const cookieString = 'key_1=value_1; key_2=value_2';
    const cookie = Cookie.fromString(cookieString);

    // -- The result cookie will contain the following cookie array
    // [
    //    { key: 'key_1', value: 'value_1' },
    //    { key: 'key_2', value: 'value_2' },
    // ]
    ```
  </Tab>
</Tabs>

#### GeolocationDonnees

`GeolocationData` contains du visiteur geolocation détails

<Note>
  Each visiteur can only have one `GeolocationData`. Adding a second `GeolocationData` overwrites the first one.
</Note>

An object parameter with the type `GeolocationInfoType` containing the following champs:

| Name                     | Type               | Description                                                                                                           |
| ------------------------ | ------------------ | --------------------------------------------------------------------------------------------------------------------- |
| country (*required*)     | `string`           | The country of le visiteur                                                                                            |
| region (*optional*)      | `string`           | The region of le visiteur                                                                                             |
| city (*optional*)        | `string`           | The city of le visiteur                                                                                               |
| postalCode (*optional*)  | `string`           | The postal code of le visiteur                                                                                        |
| coordinates (*optional*) | `[number, number]` | Coordinates array tuple of two position values (longitude and latitude). Coordinate number represents decimal degrees |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import {
      KameleoonClient,
      GeolocationData,
      GeolocationInfoType,
      useData,
      useInitialize,
    } from '@kameleoon/react-sdk';

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

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

        // -- Add geolocation data
        const geolocationInfo: GeolocationInfoType = {
          country: 'France',
          region: 'Île-de-France',
          city: 'Paris',
          postalCode: '75008',
          coordinates: [48.8738, 2.295],
        };
        const geolocationData = new GeolocationData(geolocationInfo);
        addData('my_visitor_code', geolocationData);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    import {
      KameleoonClient,
      GeolocationData,
      useData,
      useInitialize,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Add geolocation data
        const geolocationInfo = {
          country: 'France',
          region: 'Île-de-France',
          city: 'Paris',
          postalCode: '75008',
          coordinates: [48.8738, 2.295],
        };
        const geolocationData = new GeolocationData(geolocationInfo);
        addData('my_visitor_code', geolocationData);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

#### CustomData

To retain données personnalisées for future visits, le SDK transmits `CustomData` with a `Visitor` scope during the next suivi request. Vous pouvez configuré the scope in les données settings on the [données personnalisées dashboard](https://app.kameleoon.com/customData/dashboard).

`CustomData` allows you to associate any type of données with each visiteur easily. This données can then be used as a ciblage condition in [segments](/user-manual/assets/segments/create-a-segment/) or as a filter or breakdown in expérience reports.

Pour plus d'informationss about données personnalisées, please consultez this [article](/developer-docs/custom-data).

| Name                    | Type              | Description                                                                                                                                                                             | Default |
| ----------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| index/name (*required*) | `number`/`string` | Index or Name of the données personnalisées. **Either `index` or `name` doit étre provided** to identify les données.                                                                   |         |
| overwrite (*optional*)  | `boolean`         | Flag to explicitly control how la valeurs are stored and how they appear in reports. [See more](/developer-docs/custom-data#default-logic-when-overwrite-parameter-is-false-or-omitted) | `true`  |
| value (*required*)      | `string[]`        | The données personnalisées value. It doit étre stringified to match the `string` type. *Remarque :* value is variadic.                                                                  |         |

<Note>
  * Each visiteur est unllowed only one `CustomData` for each unique `index`. Adding another `CustomData` with the same `index` will replace the existing one.

  * The données personnalisées 'index' peut être found in the [Custom Données dashboard](/user-manual/assets/custom-data/manage-custom-data) under the "INDEX" column.

  * To prevenement le SDK from sending données with the selected index to Kameleoon servers for privacy reasons, enable l'option: **Use this données only locally for ciblage purposes** when creating données personnalisées.

  * Adding a `CustomData` instance created with un nom when le SDK instance n'est pas initialized or le nom n'est pas registered, will résultat in les données being ignored.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, CustomData } from '@kameleoon/react-sdk';

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

      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 overwrite flag
        const customData = new CustomData(customDataIndex, false, dataItemOne);

        // -- Create custom data using name instead of index
        const customData = new CustomData('customDataName', 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);

        // -- Create custom data using overwrite flag
        const customData = new CustomData(customDataIndex, false, ...dataList);

        // -- Create custom data using name instead of index
        const customData = new CustomData('customDataName', false, ...dataList);

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, CustomData } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        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 overwrite flag
        const customData = new CustomData(customDataIndex, false, dataItemOne);

        // -- Create custom data using name instead of index
        const customData = new CustomData('customDataName', 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);

        // -- Create custom data using overwrite flag
        const customData = new CustomData(customDataIndex, false, ...dataList);

        // -- Create custom data using name instead of index
        const customData = new CustomData('customDataName', false, ...dataList);

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

#### Device

<Note>
  Since React SDK `10.11.0`, `Device` est unutomatically detected basé sur the `User-Agent` string. Cependant, vous pouvez still manually override it if needed.

  **React Native:** Support for this feature is currently experienceal and may require adjustments to work correctly. In React Native, the `Device` est unutomatically detected basé sur the `DPI` from `react-native.Dimensions`.
</Note>

Device contains informations about your device.

<Note>
  Each visiteur can only have one `Device`. Adding a second `Device` overwrites the first one.
</Note>

| Name                    | Type         | Description                                                   |
| ----------------------- | ------------ | ------------------------------------------------------------- |
| deviceType (*required*) | `DeviceType` | possible types for device type (`PHONE`, `TABLET`, `DESKTOP`) |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      Device,
      DeviceType,
    } from '@kameleoon/react-sdk';

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

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      Device,
      DeviceType,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

#### OperatingSystem

<Note>
  Since React SDK `10.11.0`, `OperatingSystem` est unutomatically detected basé sur the `User-Agent` string. Cependant, vous pouvez still manually override it if needed.

  **React Native:** Support for this feature is currently experienceal and may require adjustments to work correctly. In React Native, the `OperatingSystem` est unutomatically detected basé sur the `react-native.Platform`.
</Note>

`OperatingSystem` contains du visiteur operating system informations.

<Note>
  Each visiteur can only have one `OperatingSystem`. Adding a second `OperatingSystem` overwrites the previous one.
</Note>

| Name                         | Type                  | Description                                                                                  |
| ---------------------------- | --------------------- | -------------------------------------------------------------------------------------------- |
| operatingSystem (*required*) | `OperatingSystemType` | possible types for device type: `WINDOWS_PHONE`, `WINDOWS`, `ANDROID`, `LINUX`, `MAC`, `IOS` |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      OperatingSystem,
      OperatingSystemType,
    } from '@kameleoon/react-sdk';

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

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

        // -- Add operating system data
        const operatingSystem = new OperatingSystem(OperatingSystemType.Windows);
        addData('my_visitor_code', operatingSystem);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      OperatingSystem,
      OperatingSystemType,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Add operating system data
        const operatingSystem = new OperatingSystem(OperatingSystemType.Windows);
        addData('my_visitor_code', operatingSystem);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

#### PageView

<Note>
  Since React SDK `10.11.0`, `PageView` est unutomatically detected basé sur the `window.location?.href` and `document.title`. Cependant, vous pouvez still manually override it if needed.

  **React Native:** Support for this feature is currently experienceal and may require adjustments to work correctly.
</Note>

PageView contains informations about your web page.

<Note>
  Each visiteur can have one `PageView` per unique URL. Adding a `PageView` with the same URL as an existing one will notify SDK that le visiteur revisited page
</Note>

`PageViewParametersType` pageViewParameters - an object with page view parameters described below

| Name                    | Type       | Description                                                                                |
| ----------------------- | ---------- | ------------------------------------------------------------------------------------------ |
| urlAddress (*required*) | `string`   | url address of the page to track                                                           |
| title (*required*)      | `string`   | title of the web page                                                                      |
| referrer (*optional*)   | `number[]` | une optional parameter containing une liste de referrers Indices, has no valeur par défaut |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      PageView,
      PageViewParametersType,
    } from '@kameleoon/react-sdk';

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

      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('my_visitor_code', pageView);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, PageView } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

#### UserAgent

Store informations on l'utilisateur-agent of le visiteur. Server-side expériences are more vulnerable to **bot traffic** than client-side expériences. To address this, Kameleoon uses the IAB/ABC International Spiders and Bots List to identify known bots and spiders. Kameleoon also uses the `UserAgent` champ to filter out bots and other unwanted traffic that could sinon skew your conversion metrics. Pour plus de détails, consultez la section help article on [bot filtering](/user-manual/faq#how-does-kameleoon-filter-bot-traffic-from-my-résultats).

If you use internal bots, we suggest that you pass la valeur **curl/8.0** of l'userAgent to exclude them from our analytics.

<Note>
  A visiteur can only have one `UserAgent`. Adding a second `UserAgent` overwrites the first one.
</Note>

| Name               | Type     | Description                   |
| ------------------ | -------- | ----------------------------- |
| value (*required*) | `string` | value utilisé pour comparison |

<Warning>
  Server-side expériences are more vulnerable to **bot traffic** than client-side expériences. To address this, Kameleoon uses the IAB/ABC International Spiders and Bots List to identify known bots and spiders. We recommend that you pass l'utilisateur agent to be filtered by Kameleoon when running server-side expériences for each visiteur browsing your website, to avoid counting bots in your analytics.

  If you use internal bots, we suggest that you pass la valeur **curl/8.0** of l'userAgent to exclude them from our analytics.
</Warning>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, UserAgent } from '@kameleoon/react-sdk';

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

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useData, UserAgent } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

#### ApplicationVersion

`ApplicationVersion` represents the semantic version number of your application.

<Tip>
  A **visiteur** can have only one `ApplicationVersion`. Adding a second instance will overwrite the first one.
</Tip>

| Name                 | Type     | Description                                                                                                                                      |
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| version (*optional*) | `string` | The mobile application version. This champ must follow semantic versioning. Accepted formats are `major`, `major.minor`, or `major.minor.patch`. |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      ApplicationVersion,
    } from '@kameleoon/react-sdk';

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

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

        // -- Add new application version data to client
        const applicationVersion = new ApplicationVersion('1.2');
        addData('my_visitor_code', applicationVersion);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useData,
      ApplicationVersion,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { addData } = useData();

      const init = useCallback(async () => {
        await initialize();

        // -- Add new application version data to client
        const applicationVersion = new ApplicationVersion('1.2');
        addData('my_visitor_code', applicationVersion);
      }, [initialize, addData]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

***

### Returned Types

#### DonneesFichier

The `DataFile` contains le SDK configuration détails.

It peut être extended with additional informations if required by clients. If you need more détails, please contact your Customer Success Manager.

| Name         | Type                       | Description                                                                       |
| ------------ | -------------------------- | --------------------------------------------------------------------------------- |
| featureFlags | `Map<string, FeatureFlag>` | A map of [`FeatureFlag`](#featureflag) objects, keyed by feature flag keys.       |
| dateModified | `number`                   | The timestamp (in milliseconds) indicating when the `DataFile` was last modified. |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { FeatureFlag } from '@kameleoon/javascript-sdk';

    // Retrieves the map of feature flags from the DataFile.
    // The map is keyed by feature flag identifiers, with each value being a FeatureFlag object.
    const featureFlags: Map<string, FeatureFlag> = dataFile.featureFlags;

    // Retrieves the last modification timestamp of the DataFile.
    // The value is a number representing milliseconds since the Unix epoch.
    const dateModified: number = dateFile.dateModified;
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    // Retrieves the map of feature flags from the DataFile.
    // The map is keyed by feature flag identifiers, with each value being a FeatureFlag object.
    const featureFlags = dataFile.featureFlags;

    // Retrieves the last modification timestamp of the DataFile.
    // The value is a number representing milliseconds since the Unix epoch.
    const dateModified = dateFile.dateModified;
    ```
  </Tab>
</Tabs>

#### FeatureFlag

The `FeatureFlag` represents a set of properties that define a feature flag itself — par exemple, its [`Variations`](#variation), [`Rules`](#rule), environnement status, and other related détails.

It peut être extended with additional informations if required by clients. If you need more détails, please contact your Customer Success Manager.

| Name                 | Type                     | Description                                                                  |
| -------------------- | ------------------------ | ---------------------------------------------------------------------------- |
| environnementEnabled | `boolean`                | Indicating whether the feature flag is enabled in the current environnement. |
| defaultVariationKey  | `string`                 | The key of the default variation associated with the feature flag.           |
| variations           | `Map<string, Variation>` | A map of `Variation` objects, keyed by variation keys.                       |
| rules                | `Rule[]`                 | A liste de `Rule` objects                                                    |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { Variation, Rule } from '@kameleoon/react-sdk';

    // Check whether the feature flag is enabled in the current environment
    const isEnvironmentEnabled: boolean = featureFlag.environmentEnabled;

    // Retrieve the key of the default variation
    const defaultVariationKey: string = featureFlag.defaultVariationKey;

    // Retrieve all variations of the feature flag as a map (key = variation key, value = Variation object)
    const variations: Map<string, Variation> = featureFlag.variations;

    // Retrieve all targeting rules associated with the feature flag
    const rules: Rule[] = featureFlag.rules;
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    // Check whether the feature flag is enabled in the current environment
    const isEnvironmentEnabled = featureFlag.environmentEnabled;

    // Retrieve the key of the default variation
    const defaultVariationKey = featureFlag.defaultVariationKey;

    // Retrieve all variations of the feature flag as a map (key = variation key, value = Variation object)
    const variations = featureFlag.variations;

    // Retrieve all targeting rules associated with the feature flag
    const rules = featureFlag.rules;
    ```
  </Tab>
</Tabs>

#### Rule

The `Rule` represents a set of properties that define a rule itself — par exemple, its [`Variations`](#variation).

It peut être extended with additional informations if required by clients. If you need more détails, please contact your Customer Success Manager.

| Name       | Type                     | Description                                            |
| ---------- | ------------------------ | ------------------------------------------------------ |
| variations | `Map<string, Variation>` | A map of `Variation` objects, keyed by variation keys. |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    import { Variation } from '@kameleoon/react-sdk';

    // Retrieve all variations of the rule as a map (key = variation key, value = Variation object)
    const variations: Map<string, Variation>  = rule.variations;
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    // Retrieve all variations of the rule as a map (key = variation key, value = Variation object)
    const variations  = rule.variations;
    ```
  </Tab>
</Tabs>

#### Variation

`Variation` contains informations about the assigned variation to le visiteur (or the default variation, if no specific assignment exists).

| Name         | Type                    | Description                                                                                         |
| ------------ | ----------------------- | --------------------------------------------------------------------------------------------------- |
| name         | `string`                | name of the variation.                                                                              |
| key          | `string`                | key of the variation.                                                                               |
| id           | `number` or `null`      | id of the variation or `null` if le visiteur landed on the default variation.                       |
| experienceId | `number` or `null`      | id of the expérience or `null` if le visiteur landed on the default variation.                      |
| variables    | `Map<string, Variable>` | map of variables for the variation, where key est le variable key and value est le variable object. |

<Note>
  * Ensure that your code handles the case where `id` or `experimentId` peut être `null`, indicating a default variation.
  * The `variables` map might be empty if no variables are associated with the variation.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    // Retrieving the variation name
    const variationName = variation.name;

    // Retrieving the variation key
    const variationKey = variation.key;

    // Retrieving the variation id
    const variationId = variation.id;

    // Retrieving the experiment id
    const experimentId = variation.experimentId;

    // Retrieving the variables map
    const variables = variation.variables;
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    // Retrieving the variation name
    const variationName = variation.name;

    // Retrieving the variation key
    const variationKey = variation.key;

    // Retrieving the variation id
    const variationId = variation.id;

    // Retrieving the experiment id
    const experimentId = variation.experimentId;

    // Retrieving the variables map
    const variables = variation.variables;
    ```
  </Tab>
</Tabs>

#### Variable

`Variable` contains informations about a variable associated with the assigned variation.

| Name  | Type     | Description                                                                                                                                   |
| ----- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| key   | `string` | The unique key identifying the variable.                                                                                                      |
| type  | `string` | The type of the variable. Possible values: **BOOLEAN**, **NUMBER**, **STRING**, **JSON**, **JS**, **CSS**.                                    |
| value | `any`    | The value of the variable, which peut être of the following types: **boolean**, **number**, **String**, **Record\<string, any>**, **any\[]**. |

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```ts theme={null}
    // Retrieving the variables map
    const variables = variation.variables;

    // Variable type can be retrieved for further processing
    const type = variables.get('isDiscount')?.type || '';

    // Retrieving the variable value by key
    const isDiscount = variables.get('isDiscount')?.value || false;

    // Variable value can be of different types
    const title = variables.get('title')?.value || '';
    ```
  </Tab>

  <Tab title="JavaScript">
    ```js theme={null}
    // Retrieving the variables map
    const variables = variation.variables;

    // Variable type can be retrieved for further processing
    const type = variables.get('isDiscount')?.type || '';

    // Retrieving the variable value by key
    const isDiscount = variables.get('isDiscount')?.value || false;

    // Variable value can be of different types
    const title = variables.get('title')?.value || '';
    ```
  </Tab>
</Tabs>

### Deprecated methods

<Warning>
  These methods are deprecated and sera removed in the next major update.
</Warning>

#### getFeatureFlagVariationKey()

* 📨 *Sends Suivi Données to Kameleoon*
* 🎯 *Événements:* `EventType.Evaluation`

<Note>
  Utilisez la [`getVariation`](#getvariation) method.
</Note>

The method `getFeatureFlagVariationKey()`, qui est used with the `useFeatureFlag` hook, retrieves the variation key for a visiteur identified by their `visitorCode`. This process includes checking the ciblage criteria, identifying the appropriate variation assigned to le visiteur, storing this informations, and sending a suivi request.

<Note>
  If a utilisateur has never been associated with a feature flag, le SDK will randomly return a variation key according to the rules of that feature flag. If l'utilisateur est unlready linked to the feature flag, le SDK will identify the previously assigned variation key. If l'utilisateur ne fait pas meet any of the specified rules, le SDK will return the valeur par défaut defined in Kameleoon's feature flag delivery rules. It's important to notez que the valeur par défaut may not always be a variation key; it could also be a boolean value or another données type, depending on how the feature flag is configured.
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getFeatureFlagVariationKey } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

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

        // -- Get visitor code using `getVisitorCode` function.
        const visitorCode = getVisitorCode();

        const featureKey = 'my_feature_key';

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getFeatureFlagVariationKey } = useFeatureFlag();
      const { getVisitorCode } = useVisitorCode();

      const init = useCallback(async () => {
        await initialize();

        // -- Get visitor code using `getVisitorCode` function
        const visitorCode = getVisitorCode();

        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, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                     | Type     | Description                                                               |
| ------------------------ | -------- | ------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | unique visiteur identification string, can't exceed 255 characters length |
| featureKey (*required*)  | `string` | a unique key for feature flag                                             |

##### Valeur de retour

| Type     | Description                                                                                          |
| -------- | ---------------------------------------------------------------------------------------------------- |
| `string` | a string containing variable key for the allocated feature flag variation for the provided visiteur. |

##### Exceptions thrown

| Type                                                  | Description                                                            |
| ----------------------------------------------------- | ---------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | Method was executed before `initialize` was done for `kameleoonClient` |
| `KameleoonException.VisitorCodeMaxLength`             | The visiteur code exceeded the maximum length (255 characters)         |
| `KameleoonException.VisitorCodeEmpty`                 | The visiteur code is empty                                             |
| `KameleoonException.FeatureFlagConfigurationNotFound` | No feature flag was found for the specified `featureKey`               |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Feature flag is disabled for the current environnement                 |

#### getVisitorFeatureFlags()

* 🚫 *Doesn't send Suivi Données to Kameleoon*
* 🎯 *Événements:* `EventType.Evaluation` (for each feature flag)

<Note>
  Utilisez la [`getVariations`](#getvariations) method.
</Note>

The `getVisitorFeatureFlags` method, utilized with the `useFeatureFlag` hook, renvoie un liste de *active* feature flags that target le visiteur associated with the `visitorCode` (le visiteur must have one of the allocated variations).

<Warning>
  Cette méthode only collects the feature flags that are currently active for le visiteur. As un resultatat, it ne fait pas include any feature flags for which le visiteur est unssigned to the "off" variation (default or control). Si vous avez besoin de retrieve all of le visiteur's feature flags, use `getFeatureFlags` instead.

  Par exemple:

  ```ts theme={null}
  // -- `getVisitorFeatureFlags` ne trigger feature experiments;
  //    it only returns feature flags where visitors didn't get the `off` variation.
  getVisitorFeatureFlags('my_visitor').forEach(({ key }) => {
    // -- `getFeatureFlagVariationKey` triggers a feature experiment,
    //    as `off` is already filtered out - visitors will never take part
    //    in an experiment where the `off` variation was allocated.
    getFeatureFlagVariationKey('my_visitor', key);
  });
  ```

  For cases where you need all of du visiteur feature flags, use [`getFeatureFlags`](#getfeatureflags) instead:

  ```ts theme={null}
  // -- Both `off` and other variations are processed as expected
  getFeatureFlags('my_visitor').forEach(({ key }) => {
    getFeatureFlagVariationKey('my_visitor', key);
  });
  ```
</Warning>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getVisitorFeatureFlags } = useFeatureFlag();

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

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getVisitorFeatureFlags } = useFeatureFlag();

      const init = useCallback(async () => {
        await initialize();

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                     | Type     | Description                                                               |
| ------------------------ | -------- | ------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | unique visiteur identification string, can't exceed 255 characters length |

##### Valeur de retour

| Type                | Description                                                             |
| ------------------- | ----------------------------------------------------------------------- |
| `FeatureFlagType[]` | liste de feature flags, each feature flag item contains `id` and `key`. |

##### Exceptions thrown

| Type                                      | Description                                                                        |
| ----------------------------------------- | ---------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | Method was executed before the `kameleoonClient` completed c'est `initialize` call |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length (255 characters)                     |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                                         |
| `KameleoonException.StorageRead`          | Erreur while reading storage données                                               |

***

#### getActiveFeatureFlags()

* 🚫 *Doesn't send Suivi Données to Kameleoon*
* 🎯 *Événements:* `EventType.Evaluation` (for each feature flag)

<Note>
  Utilisez la [`getVariations`](#getvariations) method.
</Note>

The `getActiveFeatureFlags` method, collected with the `useFeatureFlag` hook, renvoie un `Map`, where key is feature key and value is detailed informations about du visiteur variation and c'est variables

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getActiveFeatureFlags } = useFeatureFlag();

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

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

        // -- Get active feature flags for visitor
        //    with detailed variation and variables data
        const activeFeatures = getActiveFeatureFlags(visitorCode);

        // -- Result example:
        // Map {
        //   'feature-key-one' => {
        //     id: 100,
        //     key: 'variation-key-one',
        //     experimentId: 200,
        //     variables: [
        //      { key: 'variable_bool', type: VariableType.Boolean, value: true },
        //     ]
        //   },
        //   'feature-key-two' => {
        //     id: null, // -> `null` because it is default variation
        //     key: 'default-variation-key',
        //     experimentId: null, // -> `null` because it is default variation
        //     variables: []
        //   }
        // }
      }, [initialize, visitorCode, getVisitorFeatureFlags, getVisitorCode]);

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

    init();
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getActiveFeatureFlags } = useFeatureFlag();

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

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

        // -- Get active feature flags for visitor
        //    with detailed variation and variables data
        const activeFeatures = getActiveFeatureFlags(visitorCode);

        // -- Result example:
        // Map {
        //   'feature-key-one' => {
        //     id: 100,
        //     key: 'variation-key-one',
        //     experimentId: 200,
        //     variables: [
        //      { key: 'variable_bool', type: VariableType.Boolean, value: true },
        //     ]
        //   },
        //   'feature-key-two' => {
        //     id: null, // -> `null` because it is default variation
        //     key: 'default-variation-key',
        //     experimentId: null, // -> `null` because it is default variation
        //     variables: []
        //   }
        // }
      }, [initialize, visitorCode, getVisitorFeatureFlags, getVisitorCode]);

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

    init();
    ```
  </Tab>
</Tabs>

<Warning>
  Cette méthode only collects du visiteur *active* feature flags. This means le resultatat excludes all the feature flags for which le visiteur est unssigned to the `off` (default or control) variation. Lorsque vous need all of du visiteur feature flags to iterate over, use `getFeatureFlags` instead.

  Consultez la section [getVisitorFeatureFlags](#getvisitorfeatureflags) *CAUTION* section method pour plus de détails.
</Warning>

##### Arguments

| Name                     | Type     | Description                                                               |
| ------------------------ | -------- | ------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | unique visiteur identification string, can't exceed 255 characters length |

##### Valeur de retour

| Type                                  | Description                                                                                                                         |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `Map<string, KameleoonVariationType>` | a map of feature flags, where key is feature key and value is detailed informations about du visiteur variation and c'est variables |

##### Exceptions thrown

| Type                                      | Description                                                                        |
| ----------------------------------------- | ---------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | Method was executed before the `kameleoonClient` completed c'est `initialize` call |
| `KameleoonException.VisitorCodeMaxLength` | The visiteur code exceeded the maximum length of 255 characters                    |
| `KameleoonException.VisitorCodeEmpty`     | The visiteur code is empty                                                         |
| `KameleoonException.StorageRead`          | Erreur while reading storage données                                               |
| `KameleoonException.NumberParse`          | Couldn't parse Number value                                                        |
| `KameleoonException.JSONParse`            | Couldn't parse JSON value                                                          |

***

#### getFeatureFlagVariable()

* 📨 *Sends Suivi Données to Kameleoon*
* 🎯 *Événements:* `EventType.Evaluation`

<Note>
  Utilisez la [`getVariation`](#getvariation) method.
</Note>

The `getFeatureFlagVariable` method, collected with `useFeatureFlag` hook, renvoie un variable for le visiteur under `visitorCode` in the found feature flag, this includes ciblage check, finding the according variation exposed to le visiteur and saving it to storage along with sending suivi request.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useVisitorCode,
      useFeatureFlag,
      VariableType,
      JSONType,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getFeatureFlagVariable } = useFeatureFlag();

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

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

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useVisitorCode,
      useFeatureFlag,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getFeatureFlagVariable } = useFeatureFlag();

      const init = useCallback(async () => {
        await initialize();

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

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

        const { type, value } = variableResult;
      }, [initialize, getFeatureFlagVariable, visitorCode, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

Parameters object of type `GetFeatureFlagVariableParamsType` containing the following champs:

| Name                     | Type     | Description                                                                                                               |
| ------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | unique visiteur identification string, can't exceed 255 characters length                                                 |
| featureKey (*required*)  | `string` | a unique key for feature flag                                                                                             |
| variableKey (*required*) | `string` | key of the variable to be found for a feature flag with the specified `featureKey`, peut être found on Kameleoon Platform |

##### Valeur de retour

| Type                      | Description                                                                                                                                                                                                      |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FeatureFlagVariableType` | a variable object containing `type` and `value` champs. Vous pouvez check the `type` champ against `VariableType` enum. Par exemple, if the `type` is `VariableType.BOOLEAN` then `value` sera a `boolean` type. |

##### Exceptions thrown

| Type                                                  | Description                                                                     |
| ----------------------------------------------------- | ------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | Method was executed before `initialize` was done for `kameleoonClient`          |
| `KameleoonException.VisitorCodeMaxLength`             | The visiteur code exceeded the maximum length (255 characters)                  |
| `KameleoonException.VisitorCodeEmpty`                 | The visiteur code is empty                                                      |
| `KameleoonException.FeatureFlagConfigurationNotFound` | No feature flag was found for the specified `featureKey`                        |
| `KameleoonException.FeatureFlagVariableNotFound`      | No feature variable was found for the specified `visitorCode` and `variableKey` |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Feature flag is disabled for the current environnement                          |
| `KameleoonException.JSONParse`                        | Couldn't parse JSON value                                                       |
| `KameleoonException.NumberParse`                      | Couldn't parse Number value                                                     |

#### getFeatureFlagVariables()

* 📨 *Sends Suivi Données to Kameleoon*
* 🎯 *Événements:* `EventType.Evaluation` (for each feature flag)

<Note>
  Utilisez la [`getVariations`](#getvariations) method.
</Note>

The `getFeatureFlagVariables` method, collected with the `useFeatureFlag`, hook renvoie un liste de variables for le visiteur under `visitorCode` in the found feature flag, this includes ciblage check, finding the according variation exposed to le visiteur and saving it to storage along with sending suivi request.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent(): JSX.Element {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getFeatureFlagVariables } = useFeatureFlag();

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

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

        // -- Get a list of variables for the visitor under `visitorCode` in the feature flag
        const variables = getFeatureFlagVariables(visitorCode, 'my_feature_key');
      }, [initialize, getFeatureFlagVariables, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import {
      useInitialize,
      useFeatureFlag,
      useVisitorCode,
    } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getVisitorCode } = useVisitorCode();
      const { getFeatureFlagVariables } = useFeatureFlag();

      const init = useCallback(async () => {
        await initialize();

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

        // -- Get a list of variables for the visitor under `visitorCode` in the feature flag
        const variables = getFeatureFlagVariables(visitorCode, 'my_feature_key');
      }, [initialize, getFeatureFlagVariables, getVisitorCode]);

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                     | Type     | Description                                                               |
| ------------------------ | -------- | ------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | unique visiteur identification string, can't exceed 255 characters length |
| featureKey (*required*)  | `string` | a unique key for feature flag                                             |

##### Valeur de retour

| Type                          | Description                                                                                                                                                                                                                         |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FeatureVariableResultType[]` | une liste de variable objects containing `key`, `type` and `value` champs. Vous pouvez check the `type` champ against `VariableType` enum. Par exemple, if the `type` is `VariableType.BOOLEAN` then `value` sera a `boolean` type. |

##### Exceptions thrown

| Type                                                  | Description                                                                        |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | Method was executed before the `kameleoonClient` completed c'est `initialize` call |
| `KameleoonException.VisitorCodeMaxLength`             | The visiteur code exceeded the maximum length (255 characters)                     |
| `KameleoonException.VisitorCodeEmpty`                 | The visiteur code is empty                                                         |
| `KameleoonException.FeatureFlagConfigurationNotFound` | No feature flag was found for the specified `featureKey`                           |
| `KameleoonException.FeatureFlagVariationNotFound`     | No feature variation was found for the specified `visitorCode` and `variableKey`   |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Feature flag is disabled for the current environnement                             |
| `KameleoonException.JSONParse`                        | Couldn't parse JSON value                                                          |
| `KameleoonException.NumberParse`                      | Couldn't parse Number value                                                        |

***

#### onConfigurationUpdate()

<Note>
  Utilisez la `onEvent` method with `EventType.ConfigurationUpdate` instead.
</Note>

Method `onConfigurationUpdate` collected with `useInitialize` hook fires a callback on client configuration update.

<Note>
  Ce hook only works for server sent événements of real time update
</Note>

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize } from '@kameleoon/react-sdk';

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

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize, onConfigurationUpdate } = useInitialize();

      const init = useCallback(async () => {
        await initialize();

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Arguments

| Name                  | Type         | Description                                                                     |
| --------------------- | ------------ | ------------------------------------------------------------------------------- |
| callback (*required*) | `() => void` | callback function with no parameters that sera called upon configuration update |

##### Exceptions thrown

| Type                                | Description                                                                      |
| ----------------------------------- | -------------------------------------------------------------------------------- |
| `KameleoonException.Initialization` | Method was executed before the `kameleoonClient` completed its `initialize` call |

***

#### getFeatureFlags()

🚫 *Doesn't send Suivi Données to Kameleoon*

The `getFeatureFlags` method collected with the `useFeatureFlag` hook renvoie un liste de feature flags stored in le client configuration.

<Tabs defaultTabIndex={0}>
  <Tab title="TypeScript">
    ```tsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useFeatureFlag } from '@kameleoon/react-sdk';

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

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

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```jsx theme={null}
    import { useEffect, useCallback } from 'react';
    import { useInitialize, useFeatureFlag } from '@kameleoon/react-sdk';

    function MyComponent() {
      const { initialize } = useInitialize();
      const { getFeatureFlags } = useFeatureFlag();

      const init = useCallback(async () => {
        await initialize();

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

      useEffect(() => {
        init();
      }, [init]);
    }
    ```
  </Tab>
</Tabs>

##### Valeur de retour

| Type                | Description                                                             |
| ------------------- | ----------------------------------------------------------------------- |
| `FeatureFlagType[]` | liste de feature flags, each feature flag item contains `id` and `key`. |

##### Exceptions thrown

| Type                                | Description                                                                        |
| ----------------------------------- | ---------------------------------------------------------------------------------- |
| `KameleoonException.Initialization` | Method was executed before the `kameleoonClient` completed c'est `initialize` call |
