> ## 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 Native

> Intégrez le SDK React de Kameleoon pour exécuter des expériences et activer des feature flags dans les applications React à l'aide de hooks et de composants.

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

**Pour commencer** : pour obtenir de l'aide afin de démarrer, consultez le [guide du développeur](#developer-guide)

**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 [reference](#reference).

**Prérequis** : le SDK React requiert `React 16.8.0+`

## Developer guide

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

### Getting started

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. Ce **SDK Installer** vous aide à installer le SDK de votre choix, à générer un échantillon 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
```

#### Create the Kameleoon Client

Pour commencer, créez un point d'entrée pour le SDK React en créant un Kameleoon Client au niveau supérieur de votre application. Créez une instance de `KameleoonClient` en utilisant la fonction `createClient()`, importée depuis le 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>

#### Wrap the application in the Kameleoon Provider

La deuxième étape consiste à connecter le Kameleoon Client précédemment créé à `KameleoonProvider` en passant le client configuré à `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 server-side rendering (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 server-side rendering (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 server-side rendering (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 on the server (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 server-side rendering (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 on the server (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 englobant votre application pour accéder à `KameleoonClient`. Cela garantit que votre application ne scintille pas en raison de modifications de flag au démarrage.

###### Props

| Nom                   | Type              | Description                                           |
| --------------------- | ----------------- | ----------------------------------------------------- |
| children (*required*) | `ReactNode`       | éléments enfants du provider                          |
| client (*required*)   | `KameleoonClient` | instance `KameleoonClient` créée par `createClient()` |

##### KameleoonProviderSSR

Utilisez ce provider au niveau racine en englobant votre application pour accéder à `KameleoonClient`.
`KameleoonProviderSSR` diffère de `KameleoonProvider` en ce qu'il crée une instance `KameleoonClient` à l'intérieur du contexte lors de la première requête client. Cela évite le risque de créer le client côté serveur. Il est recommandé pour une utilisation dans les systèmes basés sur le SSR, tels que Next.js avec SSR.

###### Props

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

#### Await for the client initialization

L'initialisation de `KameleoonClient` se fait de manière asynchrone afin de garantir que l'appel à l'API Kameleoon a réussi ; pour cela, le hook `useInitialize` est utilisé. Vous pouvez utiliser `async/await`, `Promise.then()` ou toute autre méthode pour gérer l'initialisation asynchrone du client.

<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 user

Pour attribuer un identifiant unique à un utilisateur, vous pouvez utiliser la méthode [`getVisitorCode()`](#getvisitorcode). Si un **visitor code** n'existe pas (à partir du cookie des en-têtes de requête), la méthode génère un identifiant unique aléatoire ou utilise un `defaultVisitorCode` que vous auriez généré. L'identifiant est ensuite défini dans un cookie des en-têtes de réponse.

Si vous utilisez Kameleoon en [mode Hybride](/developer-docs/feature-experimentation/get-started/hybrid-experimentation), l'appel à la méthode `getVisitorCode()` garantit que l'identifiant unique (**visitor code**) est partagé entre le fichier d'application `engine.js` (anciennement nommé `kameleoon.js`) et le SDK.

##### Retrieving a flag configuration

Pour implémenter un feature flag dans votre code, vous devez d'abord créer le feature flag dans votre compte Kameleoon.

Pour déterminer le statut ou la variation d'un feature flag pour un utilisateur spécifique, vous devez utiliser la méthode [`getVariation()`](#getvariation) ou [`isFeatureFlagActive()`](#isfeatureflagactive) pour récupérer la configuration en fonction du `featureKey`.

La méthode `getVariation()` gère à la fois les feature flags simples avec des états ON/OFF et les flags plus complexes avec plusieurs variations. La méthode récupère la variation appropriée pour l'utilisateur en vérifiant les règles de la fonctionnalité, en attribuant la variation et en la renvoyant en fonction du `featureKey` et du `visitorCode`.

La méthode `isFeatureFlagActive()` peut être utilisée si vous souhaitez récupérer la configuration d'un feature flag simple qui n'a qu'un état ON ou OFF, par opposition aux feature flags plus complexes avec plusieurs variations ou options de ciblage.

Si votre feature flag a des variables associées (telles que des comportements spécifiques liés à chaque variation), `getVariation()` vous permet également d'accéder à l'objet [`Variation`](#variation), qui fournit des détails sur la variation attribuée et son expérience associée. Cette méthode vérifie si l'utilisateur est ciblé, trouve la variation attribuée au visiteur et l'enregistre dans le stockage. Lorsque `track=true`, le SDK enverra l'événement d'exposition à l'expérience spécifiée lors de la prochaine requête de suivi, qui est automatiquement déclenchée en fonction du [`tracking_interval_millisecond`](#configuration-parameters) du SDK. Par défaut, cet intervalle est défini sur 1000 millisecondes (1 seconde).

La méthode `getVariation()` vous permet de contrôler si le suivi est effectué. Si `track=false`, aucun événement d'exposition ne sera envoyé par le SDK. Cela est utile si vous préférez ne pas suivre les données via le SDK et plutôt vous appuyer sur le suivi côté client géré par le moteur Kameleoon, par exemple. De plus, définir `track=false` est utile lors de l'utilisation de la méthode `getVariations()`, où vous pouvez n'avoir besoin que des variations pour tous les flags sans déclencher d'événements de suivi. Si vous souhaitez en savoir plus sur le fonctionnement du suivi, consultez [cet article](/developer-docs/feature-experimentation/technical-reference/faq-global#when-does-the-sdk-send-a-tracking-request-for-analytics)

##### Adding data points to target a user or filter / breakdown visits in reports

Pour cibler un utilisateur, assurez-vous d'avoir ajouté les points de données pertinents à son profil avant de récupérer la variation de la fonctionnalité ou de vérifier si le flag est actif. Utilisez la méthode [`addData()`](#adddata) pour ajouter ces points de données au profil de l'utilisateur.

Pour récupérer les points de données collectés sur d'autres appareils ou pour accéder aux données utilisateur passées (collectées côté client lors de l'utilisation de Kameleoon en mode Hybride), utilisez la méthode [`getRemoteVisitorData()`](#getremotevisitordata). Cette méthode récupère les données de manière asynchrone à partir des serveurs. Il est important d'appeler `getRemoteVisitorData()` *avant* de récupérer la variation ou de vérifier si le feature flag est actif, car ces données peuvent être nécessaires pour attribuer un utilisateur à une variation donnée.

Pour en savoir plus sur les conditions de ciblage disponibles, consultez [l'article détaillé à ce sujet](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation).

De plus, les points de données que vous ajoutez au profil du visiteur seront disponibles lors de l'analyse de vos expériences, vous permettant de filtrer et de décomposer vos résultats par facteurs tels que l'appareil et le navigateur. Le mode Hybride de Kameleoon collecte automatiquement une variété de points de données côté client, facilitant la décomposition de vos résultats en fonction de ces points de données pré-collectés. Voir la liste complète [ici](/fr/user-manual/experiment-analytics/analyze-results/results-page/results-page-settings#ventiler-l’audience).

Si vous devez suivre des points de données supplémentaires au-delà de ce qui est collecté automatiquement, vous pouvez utiliser la [fonctionnalité Custom Data de Kameleoon](#customdata). Custom Data vous permet de capturer et d'analyser des informations spécifiques pertinentes pour vos expériences. N'oubliez pas d'appeler la méthode [`flush()`](#flush) pour envoyer les données collectées aux serveurs Kameleoon pour analyse.

<Note>
  Pour garantir que vos résultats sont précis, il est recommandé de filtrer les bots en utilisant le type de données [`UserAgent`](#useragent).
</Note>

##### Tracking goal conversions

Lorsqu'un utilisateur effectue une action souhaitée (telle qu'un achat), elle est enregistrée comme une conversion. Pour suivre les conversions, utilisez la méthode [`trackConversion()`](#trackconversion) et fournissez les paramètres requis `visitorCode` et `goalId`.

La requête de suivi de conversion sera envoyée avec la prochaine requête de suivi planifiée, que le SDK envoie à intervalles réguliers (définis par [`tracking_interval_millisecond`](#configuration-parameters)). Si vous préférez envoyer la requête immédiatement, utilisez la méthode [`flush()`](#flush) avec le paramètre `instant=true`.

##### Sending events to analytics solutions

Pour suivre les conversions et envoyer des événements d'exposition à votre solution d'analyse client, vous devez d'abord implémenter Kameleoon en [mode Hybride](/developer-docs/feature-experimentation/get-started/hybrid-experimentation/). Ensuite, utilisez la méthode [`getEngineTrackingCode()`](#getenginetrackingcode).

La méthode `getEngineTrackingCode()` récupère le code de suivi unique nécessaire pour envoyer des événements d'exposition à votre solution d'analyse. L'utilisation de cette méthode vous permet d'enregistrer des événements et de les envoyer à la plateforme d'analyse de votre choix.

### React Native considerations

<Note>
  React Native sur la plateforme `android` ne prend pas en charge la fonctionnalité `Real Time Update`.
</Note>

Bien que le SDK React fonctionne de la même manière dans les contextes React Native et React, il est important de noter que les étapes de configuration diffèrent.
En raison de l'absence d'API navigateur dans React Native, le SDK React doit avoir différentes implémentations de [dépendances externes](#external-dependencies) pour fonctionner correctement.
Pour cela, Kameleoon fournit plusieurs packages npm dédiés que vous pouvez installer et configurer manuellement ou installer via le [Kameleoon SDK Installation Tool](#installation) (recommandé).

Les packages incluent :

* `@kameleoon/react-native-storage` - construit avec la bibliothèque `react-native-mmkv`
* `@kameleoon/react-native-event-source` - construit avec la bibliothèque `react-native-event-source-ts`
* `@kameleoon/react-native-visitor-code-manager` - construit sur la base de la bibliothèque `react-native-mmkv`
* `@kameleoon/react-native-platform-analyzer` - construit avec la bibliothèque `react-native`
* *optional* `@kameleoon/react-native-secure-prng` - construit avec la bibliothèque `react-native-get-random-values`

Si vous ne souhaitez pas utiliser les packages listés, vous pouvez fournir votre propre implémentation en suivant [le guide des dépendances externes](#external-dependencies).

Exemple de configuration du SDK React pour une application React Native :

<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 utilise un ID de visiteur unique et anonyme (`visitorCode`) pour attribuer les utilisateurs aux variations de feature flag. Cet ID est généralement généré et stocké sur l'appareil de l'utilisateur (dans un cookie de navigateur pour les SDK côté client et côté serveur — dans le stockage persistant pour les SDK mobiles). Cependant, dans certains scénarios, vous pouvez avoir besoin de garantir que tous les utilisateurs d'une même organisation voient la même variante d'un feature flag.

L'option **Custom Bucketing Key** vous permet de remplacer ce comportement par défaut en fournissant votre propre identifiant personnalisé pour le bucketing. Ce remplacement garantit que la logique d'attribution de Kameleoon utilise votre clé spécifiée au lieu du `visitorCode` par défaut.

#### Use cases

Utiliser une clé de bucketing personnalisée est essentiel pour maintenir la cohérence et la précision de vos attributions de feature flag, en particulier dans ces situations :

* **Expériences au niveau du compte ou de l'organisation :** Pour les produits B2B ou les scénarios où vous souhaitez attribuer tous les utilisateurs d'une même organisation à la même variation, vous pouvez utiliser un identifiant tel qu'un `accountId`. Les clés de bucketing personnalisées sont cruciales pour les fonctionnalités d'A/B test qui impactent une équipe ou une entreprise entière.

En implémentant une clé de bucketing personnalisée, vous assurez une plus grande cohérence et précision dans vos expériences, conduisant à des résultats plus fiables et à une meilleure expérience utilisateur.

#### Technical details

Lorsque vous configurez une clé de bucketing personnalisée pour un feature flag, vous fournissez à Kameleoon un identifiant spécifique provenant des données de votre application :

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

<Tip>
  [Plus d'informations dans addData()](#adddata)
</Tip>

* **Fournir la clé personnalisée :** Vous fournissez votre identifiant personnalisé au SDK Kameleoon à l'aide de la méthode [`addData()`](#adddata). Dans cette méthode, vous passerez votre clé de bucketing personnalisée choisie en tant qu'objet [`CustomData`](#customdata). Ici, `newVisitorCode` fait référence à l'identifiant que vous souhaitez utiliser pour votre bucketing (par exemple, le nouveau `userId` ou `accountId`).

<Warning>
  Pour que la clé de bucketing personnalisée fonctionne correctement, elle doit également être définie et configurée pour le feature flag pendant le processus de création ou de modification du flag. Sans cette configuration correspondante, le bucketing du SDK n'appliquera pas votre clé personnalisée. Pour des instructions détaillées sur la façon de le configurer dans Kameleoon, reportez-vous à cet [article](/user-manual/experimentation/feature-experimentation/create-and-manage-flags/create-a-feature-flag#Advanced_Flag_Settings).
</Warning>

* **Logique de bucketing :** Une fois qu'une clé de bucketing personnalisée est fournie via la méthode `addData()`, tous les calculs de hash pour attribuer les utilisateurs aux variations utiliseront ce `newVisitorCode` (votre clé personnalisée) au lieu du `visitorCode` par défaut. Utiliser le `newVisitorCode` signifie que la décision de bucketing est liée à votre identifiant personnalisé, garantissant des attributions cohérentes à travers les différents contextes où cet identifiant est présent.
* **Suivi des données et analytique :** Il est essentiel de noter que bien que le `newVisitorCode` (votre clé personnalisée) soit utilisé pour les décisions de bucketing, **toutes les données ultérieures (événements de suivi et conversions, par exemple) sont envoyées et associées au `visitorCode` *original*.** Cette séparation garantit que vos analytiques reflètent avec précision les parcours et interactions individuels des utilisateurs dans le contexte plus large de votre expérience, même lorsque le bucketing est effectué à un niveau supérieur (comme un compte) ou à travers plusieurs appareils/sessions. Vos données de visiteur d'origine restent intactes pour des rapports complets.

#### Technical requirementes

Pour utiliser efficacement une clé de bucketing personnalisée :

* La clé doit être une `string`.
* Elle doit être unique pour l'entité que vous avez l'intention de bucketer (par exemple, si vous utilisez un `userId`, l'ID de chaque utilisateur doit être unique).
* La clé doit être disponible pour le SDK au moment exact où la décision de feature flag est évaluée pour cet utilisateur ou cette requête.

### Targeting conditions

Les SDK Kameleoon prennent en charge une variété de conditions de ciblage prédéfinies que vous pouvez utiliser pour cibler les utilisateurs dans vos campagnes.
Pour la liste des conditions prises en charge par ce SDK, consultez [use visit history to target users](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation).

Vous pouvez également utiliser vos propres [données externes pour cibler les utilisateurs](/developer-docs/feature-experimentation/targeting-and-segmentation\use-external-data-to-target-users).

### Logging

Le SDK génère des logs pour refléter divers processus internes et problèmes.

#### Log levels

Le SDK prend en charge la configuration de la limitation du logging par niveau de log.

<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

Le SDK écrit ses logs dans la sortie console par défaut. Ce comportement peut être remplacé.

<Note>
  La limitation du logging par niveau de log est effectuée indépendamment de la logique de gestion des logs.
</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 information

Vous fournissez un domaine en tant que `domain` dans la \[configuration] de `KameleoonClient`, qui est utilisé pour stocker le visitor code Kameleoon dans les cookies. Ceci est important lorsque vous travaillez avec les méthodes [`getVisitorCode`](#getvisitorcode) et [`setLegalConsent`](#setlegalconsent). Le domaine que vous fournissez est stocké dans le cookie en tant que clé `Domain=`.

#### Setting the domain

Le domaine que vous fournissez indique que l'adresse URL peut utiliser le cookie. Par exemple, si votre domaine est `www.example.com`, le cookie n'est disponible qu'à partir d'une URL `www.example.com`. Cela signifie que les pages avec le domaine `app.example.com` ne peuvent pas utiliser le cookie.

Pour être plus flexible avec les sous-domaines, vous pouvez préfixer un domaine par `.`. Par exemple, le domaine `.example.com` permet au cookie de fonctionner à la fois sur `app.example.com` et `login.example.com`.

<Note>
  Vous ne pouvez pas utiliser d'expressions régulières, de symboles spéciaux, de protocole ou de numéros de port dans le `domain`.
  De plus, une [liste spécifique de sous-domaines](https://publicsuffix.org/list/public_suffix_list.dat) n'est pas autorisée à être utilisée avec le préfixe `.`.
</Note>

Voici une petite fiche de référence sur les domaines :

| Domaine                        | URL autorisées        | URL non autorisées   |
| ------------------------------ | --------------------- | -------------------- |
| `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`      | ⛔ domaine invalide    | ⛔ domaine invalide   |
| `www.example.com:4408`         | ⛔ domaine invalide    | ⛔ domaine invalide   |
| `.localhost.com` = `localhost` | ⛔ domaine invalide    | ⛔ domaine invalide   |

#### Developing on localhost

`localhost` est toujours considéré comme un domaine invalide, ce qui rend difficile le test du domaine lors du développement sur localhost.

Il existe deux façons d'éviter ce problème :

* Ne pas spécifier le champ `domain` dans le client SDK lors des tests. Cela évite les problèmes de `localhost` (le cookie sera défini sur n'importe quel domaine).
* Créer un domaine local pour `localhost`. Par exemple :
  * Naviguez vers `/etc/hosts` sur *Linux* ou vers `c:\Windows\System32\Drivers\etc\hosts` sur *Windows*
  * Ouvrez `hosts` avec les droits de super-utilisateur ou d'administrateur
  * Ajoutez un domaine au port localhost, par exemple : `127.0.0.1 app.com`
  * Vous pouvez maintenant exécuter votre application localement sur `app.com:{my_port}` et spécifier `.app.com` comme votre domaine

### External dependencies

Les dépendances externes du SDK utilisent le modèle *dependency injection* pour vous donner la possibilité de fournir vos propres implémentations pour certaines parties d'un SDK.

<Note>
  Dans le SDK React, toutes les dépendances externes ont des implémentations par défaut, qui utilisent une API native du navigateur, il n'est donc pas nécessaire de les fournir à moins qu'une autre API ne soit requise pour des cas d'utilisation spécifiques.
</Note>

Voici la liste des dépendances externes disponibles :

| Dépendance                        | Interface                     | API utilisée                                            | Description                                                                                                                                                                                             |
| --------------------------------- | ----------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage` (*optional*)            | `IExternalStorage`            | `localStorage` du navigateur                            | Utilisé pour stocker toutes les données existantes et collectées du SDK                                                                                                                                 |
| `requester` (*optional*)          | `IExternalRequester`          | `fetch` du navigateur                                   | Utilisé pour effectuer toutes les requêtes réseau                                                                                                                                                       |
| `eventSource` (*optional*)        | `IExternalEventSource`        | `EventSource` du navigateur                             | Utilisé pour recevoir les Server Sent Events pour les capacités de [Real Time Update](/fr/developer-docs/feature-experimentation/technical-reference/technical-considerations#streaming-option-premium) |
| `visitorCodeManager` (*optional*) | `IExternalVisitorCodeManager` | Cookie du navigateur                                    | Utilisé pour stocker et synchroniser le visitor code                                                                                                                                                    |
| `prng` (*optional*)               | `IExternalPRNG`               | `Math.random` ou `crypto.getRandomValues` du navigateur | Utilisé pour générer des ID uniques pour les événements de suivi                                                                                                                                        |
| `logger` (*optional*)             | `ILogger`                     | Implémentation personnalisée                            | Utilisé pour la gestion personnalisée des logs du SDK. Permet de définir comment les logs sont traités et où ils sont émis.                                                                             |
| `platformAnalyzer` (*optional*)   | `IPlatformAnalyzer`           | API React Native                                        | Détecte automatiquement la plateforme et attache cette information aux données du visiteur. Conçu spécifiquement pour React Native.                                                                     |

L'exemple suivant implémente les dépendances externes. Pour importer une interface depuis un SDK, créez une classe qui l'implémente et passez la classe instanciée au 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>

#### EventSource

<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>
  [Renvoyer un résultat simulé](#simulatesuccessrequest)
</Tip>

#### Pseudo Random Number Generator

Le Pseudo Random Number Generator (PRNG) est une dépendance qui génère un nombre à virgule flottante aléatoire entre `0` et `1` (similaire à `Math.random`).

L'implémentation par défaut de Kameleoon repose sur la fonction `crypto` du navigateur ou sur `Math.random` si `crypto` n'est pas disponible.
Ces API sont très sécurisées et fiables, cependant dans certains cas particuliers (en particulier dans certains moteurs `React Native`), vous pouvez vouloir fournir votre propre implémentation ou utiliser un package Kameleoon dédié à 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>

### Error Handling

Presque chaque callback du SDK React renvoyé par les hooks peut générer une erreur à un moment donné ; ces erreurs ne sont pas de simples cas particuliers mais plutôt des `KameleoonError` délibérément prédéfinis
qui étendent la classe native `Error` de JavaScript en fournissant des messages utiles et un champ spécial `type` de type `KameleoonException`.

`KameleoonException` est une enum contenant tous les types d'erreur possibles.

Pour savoir exactement quel type de `KameleoonException` les callbacks peuvent générer, vous pouvez consulter la section `Throws` de la description des hooks sur cette page ou simplement survoler le callback dans votre IDE pour voir la description jsdoc.

Dans l'ensemble, gérer les erreurs est considéré comme une bonne pratique pour rendre votre application plus stable et éviter les problèmes techniques.

***

<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

Pour prendre en charge les visiteurs qui accèdent à une application depuis plusieurs appareils, Kameleoon permet la synchronisation des données de visiteur précédemment collectées sur chacun des appareils du visiteur et la réconciliation de leur historique de visites entre appareils via l'expérimentation cross-device. Des études de cas et des informations détaillées sur la façon dont Kameleoon gère les données entre appareils sont disponibles dans l'[article sur l'expérimentation cross-device](/developer-docs/cross-device-experimentation).

#### Synchronizing custom data across devices

Bien que la synchronisation de mapping personnalisé soit utilisée pour aligner les données du visiteur entre les appareils, elle n'est pas toujours nécessaire. Voici deux scénarios où la synchronisation de mapping personnalisée n'est pas requise :

**Même ID utilisateur entre appareils**
Si le même ID utilisateur est utilisé de manière cohérente sur tous les appareils, la synchronisation est gérée automatiquement sans synchronisation de mapping personnalisé. Il suffit d'appeler la méthode `getRemoteVisitorData()` lorsque vous souhaitez synchroniser les données collectées entre plusieurs appareils.

**Instances multi-serveurs avec des ID cohérents**
Dans les configurations complexes impliquant plusieurs serveurs (par exemple, des instances de serveurs distribués), où le même ID utilisateur est disponible sur tous les serveurs, la synchronisation entre serveurs (avec `getRemoteVisitorData()`) est suffisante sans synchronisation de mapping personnalisé supplémentaire.

Les clients ayant besoin de données supplémentaires peuvent se référer à la description de la méthode [`getRemoteVisitorData()`](#getremotevisitordata) pour obtenir des conseils supplémentaires. Dans le code ci-dessous, il est supposé que le même identifiant unique (dans ce cas, le `visitorCode`, qui peut également être appelé `userId`) est utilisé de manière cohérente entre les deux appareils pour une récupération précise des données.

<Note>
  Si vous souhaitez synchroniser les données collectées en temps réel, vous devez choisir le scope **Visitor** pour vos custom data.
</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 custom data for session merging

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    [L'expérimentation cross-device](/developer-docs/cross-device-experimentation) vous permet de combiner l'historique d'un visiteur sur chacun de ses appareils (réconciliation d'historique). L'une des fonctionnalités puissantes que la réconciliation d'historique fournit est la capacité de fusionner différentes sessions de visiteurs en une seule. Pour réconcilier l'historique des visites, vous pouvez utiliser [`CustomData`](#customdata) pour fournir un identifiant unique pour le visiteur.

    Suivez le guide [activating cross-device history reconciliation](/fr/developer-docs/cross-device-experimentation#activer-la-réconciliation-d’historique-cross-device) pour configurer vos custom data sur la plateforme Kameleoon

    Une fois vos custom data configurées, vous pouvez les utiliser dans votre code pour fusionner la session d'un visiteur.
    Les sessions avec le même identifiant verront toujours la même variation d'expérience et seront affichées comme un seul visiteur dans la vue `Visitor` des pages de résultats de votre expérience.

    La configuration du SDK garantit que les sessions associées voient toujours la même variation de l'expérience.

    Ensuite, vous pouvez utiliser le SDK normalement. Les méthodes suivantes peuvent être utiles dans le contexte de la fusion de sessions :

    * Utilisez [`getRemoteVisitorData`](#getremotevisitordata) avec `isUniqueIdentifier=true` pour récupérer les données de tous les visiteurs liés
    * Utilisez [`trackConversion`](#trackconversion) ou [`flush`](#flush) avec `isUniqueIdentifier=true` pour suivre certaines données pour un visiteur spécifique qui est associé à un autre visiteur

    <Tip>
      Comme la custom data que vous utilisez comme identifiant doit être définie sur le scope `Visitor`, vous devez utiliser la [synchronisation cross-device des custom data](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-data-across-devices) pour récupérer l'identifiant avec la méthode [`getRemoteVisitorData`](#getremotevisitordata) sur chaque appareil.
    </Tip>

    Voici un exemple d'utilisation de custom data pour la fusion de sessions. Dans cet exemple, nous avons une application avec une page de connexion. Comme nous ne connaissons pas l'ID utilisateur au moment de la connexion, nous utilisons un identifiant de visiteur anonyme généré par la méthode [`getVisitorCode`](#getvisitorcode). Après la connexion de l'utilisateur, nous pouvons associer le visiteur anonyme à l'ID utilisateur et l'utiliser comme identifiant unique pour 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">
    [L'expérimentation cross-device](/developer-docs/cross-device-experimentation) vous permet de combiner l'historique d'un visiteur sur chacun de ses appareils (réconciliation d'historique). L'une des fonctionnalités puissantes que la réconciliation d'historique fournit est la capacité de fusionner différentes sessions de visiteurs en une seule. Pour réconcilier l'historique des visites, vous pouvez utiliser [`CustomData`](#customdata) pour fournir un identifiant unique pour le visiteur.

    Suivez le guide [activating cross-device history reconciliation](/fr/developer-docs/cross-device-experimentation#activer-la-réconciliation-d’historique-cross-device) pour configurer vos custom data sur la plateforme Kameleoon

    Une fois vos custom data configurées, vous pouvez les utiliser dans votre code pour fusionner la session d'un visiteur.
    Les sessions avec le même identifiant verront toujours la même variation d'expérience et seront affichées comme un seul visiteur dans la vue `Visitor` des pages de résultats de votre expérience.

    La configuration du SDK garantit que les sessions associées voient toujours la même variation de l'expérience.

    Avant d'utiliser d'autres méthodes, assurez-vous d'informer le SDK que le visiteur est un identifiant unique en ajoutant des données [`UniqueIdentifier`](#uniqueidentifier) à un visiteur

    <Tip>
      Comme la custom data que vous utilisez comme identifiant doit être définie sur le scope `Visitor`, vous devez utiliser la [synchronisation cross-device des custom data](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-data-across-devices) pour récupérer l'identifiant avec la méthode [`getRemoteVisitorData`](#getremotevisitordata) sur chaque appareil.
    </Tip>

    Voici un exemple d'utilisation de custom data pour la fusion de sessions. Dans cet exemple, nous avons une application avec une page de connexion. Comme nous ne connaissons pas l'ID utilisateur au moment de la connexion, nous utilisons un identifiant de visiteur anonyme généré par la méthode [`getVisitorCode`](#getvisitorcode). Après la connexion de l'utilisateur, nous pouvons associer le visiteur anonyme à l'ID utilisateur et l'utiliser comme identifiant unique pour 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

Le SDK dispose d'un ensemble de méthodes utilitaires qui peuvent être utilisées pour simplifier le processus de développement. Toutes les méthodes sont représentées en tant que membres statiques de la classe `KameleoonUtils`.

#### simulateSuccessRequest

La méthode `simulateSuccessRequest` est utilisée pour simuler une requête réussie vers le serveur Kameleoon. Elle peut être utile pour les implémentations personnalisées de [Requester](#requester) lorsque le développeur a besoin de simuler une requête réussie, par exemple en désactivant le 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

| Nom                      | Type                                   | Description                                                       |
| ------------------------ | -------------------------------------- | ----------------------------------------------------------------- |
| requestType (*required*) | `RequestType`                          | Un type de requête                                                |
| data (*required*)        | `SimulateRequestDataType[RequestType]` | Un type de données de requête, qui diffère selon le `RequestType` |

Le type de données `SimulateRequestDataType` est défini comme suit :

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

##### Return value

| Type                             | Description                                        |
| -------------------------------- | -------------------------------------------------- |
| `Promise<KameleoonResponseType>` | renvoie une promesse avec la réponse de la requête |

#### getCookieValue

La méthode `getCookieValue` est utilisée pour analyser une chaîne de cookie courante (`key_1=value_1; key_2=value_2; ...`) et obtenir la valeur d'une clé de cookie spécifique. Elle est utile lorsque vous travaillez avec une implémentation personnalisée de [`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

| Nom                 | Type     | Description                                                   |
| ------------------- | -------- | ------------------------------------------------------------- |
| cookie (*required*) | `string` | Chaîne de cookie sous la forme `key_1=value_1; key_2=value_2` |
| key (*required*)    | `string` | Représentation chaîne d'une clé pour trouver une valeur       |

##### Return value

| Type     | Description |                                                                                      |
| -------- | ----------- | ------------------------------------------------------------------------------------ |
| \`string | null\`      | renvoie une chaîne avec une valeur de cookie ou `null` si la clé n'a pas été trouvée |

## Reference

Il s'agit de la documentation de référence complète pour le SDK React.

### Initialization

Cette section fournit les méthodes que vous utilisez pour créer et initialiser le Kameleoon Client dans votre application.

#### initialize()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    Une fonction asynchrone `initialize`, collectée avec le hook `useInitialize`, qui est utilisée pour l'initialisation de KameleoonClient en récupérant les données liées au SDK Kameleoon depuis le serveur ou en récupérant les données depuis une source locale si les données sont à jour ou si l'intervalle de mise à jour n'a pas été atteint.

    <Note>
      * Si la configuration du SDK n'a pas pu être récupérée mais qu'une configuration plus ancienne est disponible dans le stockage du SDK, le SDK utilise la configuration plus ancienne comme solution de repli et `initialize` ne génère pas d'erreur.

      * L'initialisation du client a un *mode hors ligne* optionnel.
        Il est activé en définissant le paramètre optionnel `useCache` sur `true`.

      En *mode hors ligne*, si les requêtes de suivi de l'une des méthodes suivantes échouent en raison de problèmes de connectivité Internet, le SDK renvoie automatiquement la requête dès qu'il détecte que la connexion Internet a été rétablie :

      * [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

    | Nom                   | Type                     | Description                                                                                                                                                                                | Valeur par défaut |
    | --------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- |
    | useCache (*optional*) | `boolean` or `undefined` | paramètre permettant d'activer le mode hors ligne du SDK ; si `true` est passé, les polls échoués ne renverront pas d'erreur et utiliseront les données en cache si elles sont disponibles | `false`           |

    ##### Return value

    | Type               | Description                                                                                                                                                                                                                                                                  |
    | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `Promise<boolean>` | une promesse résolue en un booléen indiquant une initialisation réussie du SDK. En général, `initialize` génère une erreur si quelque chose d'ingérable se produit, donc la valeur `boolean` sera presque toujours `true` et ne fournira pas beaucoup d'informations utiles. |

    ##### Exceptions thrown

    | Type                                       | Description                                                            |
    | ------------------------------------------ | ---------------------------------------------------------------------- |
    | `KameleoonException.StorageWrite`          | Impossible de mettre à jour les données du stockage                    |
    | `KameleoonException.ClientConfiguration`   | Impossible de récupérer la configuration client depuis l'API Kameleoon |
    | `KameleoonException.MaximumRetriesReached` | Nombre maximal de tentatives atteint, la requête a échoué              |
  </Tab>

  <Tab title="SDK Version 10">
    Une fonction asynchrone `initialize`, collectée avec le hook `useInitialize`, qui est utilisée pour l'initialisation de KameleoonClient en récupérant les données liées au SDK Kameleoon depuis le serveur ou en récupérant les données depuis une source locale si les données sont à jour ou si l'intervalle de mise à jour n'a pas été atteint.

    <Note>
      * Si la configuration du SDK n'a pas pu être récupérée mais qu'une configuration plus ancienne est disponible dans le stockage du SDK, le SDK utilise la configuration plus ancienne comme solution de repli et `initialize` ne génère pas d'erreur.

      * Le SDK prend en charge un *mode hors ligne*.

      En *mode hors ligne*, si les requêtes de suivi de l'une des méthodes suivantes échouent en raison de problèmes de connectivité Internet, le SDK renvoie automatiquement la requête dès qu'il détecte que la connexion Internet a été rétablie :

      * [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>

    ##### Return value

    | Type               | Description                                                                                                                                                                                                                                                                  |
    | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `Promise<boolean>` | une promesse résolue en un booléen indiquant une initialisation réussie du SDK. En général, `initialize` génère une erreur si quelque chose d'ingérable se produit, donc la valeur `boolean` sera presque toujours `true` et ne fournira pas beaucoup d'informations utiles. |

    ##### Exceptions thrown

    | Type                                       | Description                                                            |
    | ------------------------------------------ | ---------------------------------------------------------------------- |
    | `KameleoonException.StorageWrite`          | Impossible de mettre à jour les données du stockage                    |
    | `KameleoonException.ClientConfiguration`   | Impossible de récupérer la configuration client depuis l'API Kameleoon |
    | `KameleoonException.MaximumRetriesReached` | Nombre maximal de tentatives atteint, la requête a échoué              |
  </Tab>
</Tabs>

#### isInitialized()

La fonction `isInitialized`, collectée avec le hook `useInitialize`, est une petite méthode utilitaire qui vérifie si l'initialisation du SDK est terminée. Par exemple, cela peut être utile lorsque vous travaillez avec une arborescence de composants profondément imbriqués, car cela vous permet de vérifier rapidement la disponibilité du SDK sans avoir à gérer un état global, ou à passer le résultat de l'initialisation via les props des composants.

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

##### Return value

Une valeur `boolean`. Renvoie `true` si le SDK a été initialisé avec succès, sinon renvoie `false`.

#### createClient()

Pour commencer, vous devez créer un point d'entrée pour le SDK React en créant un Kameleoon Client au niveau supérieur de votre application en utilisant la fonction `createClient()` importée du package `kameleoon`.

Une instance de `KameleoonClient` est créée à l'aide de la fonction `createClient()`.

<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

Un objet de type `SDKParameters` contenant :

| Nom                        | Type                            | Description                                                                                                                                           |
| -------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| siteCode (*required*)      | `string`                        | Il s'agit d'une [clé unique](/user-manual/faq#how-do-i-find-my-sitecode) du projet Kameleoon que vous utilisez avec le SDK. Ce champ est obligatoire. |
| configuration (*optional*) | `Partial<SDKConfigurationType>` | configuration du client                                                                                                                               |
| externals (*optional*)     | `ExternalsType`                 | implémentation externe des dépendances du SDK ([External dependencies](#external-dependencies))                                                       |

##### Configuration Parameters

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    | Nom                                       | Type          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Valeur par défaut                              |
    | ----------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
    | updateInterval (*optional*)               | `number`      | Spécifie l'intervalle de rafraîchissement, en minutes, auquel le SDK récupère la configuration pour les expériences et feature flags actifs. La valeur détermine le temps maximum nécessaire pour propager les modifications, telles que l'activation ou la désactivation de feature flags ou le lancement d'expériences, vers vos serveurs de production. S'il n'est pas spécifié, l'intervalle par défaut est défini à 60 minutes. De plus, nous proposons un [mode streaming](/developer-docs/feature-experimentation/technical-reference/technical-considerations/#streaming-premium-option) qui utilise les server-sent events (SSE) pour pousser automatiquement de nouvelles configurations vers le SDK et appliquer les nouvelles configurations en temps réel, sans aucun délai. | `60`                                           |
    | environment (*optional*)                  | `Environment` | environnement du feature flag                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `Environment.Production`                       |
    | targetingDataCleanupInterval (*optional*) | `number`      | intervalle en *minutes* pour le nettoyage des données de ciblage ; la valeur minimale est de 1 minute                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `undefined` (aucun nettoyage ne sera effectué) |
    | domain (*optional*)                       | `string`      | [domaine](#domain-information) auquel appartient le cookie. Déprécié, utilisez `cookieDomain` à la place                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `undefined`                                    |
    | cookieDomain (*optional*)                 | `string`      | [domaine](#domain-information) auquel appartient le cookie.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `undefined`                                    |
    | networkDomain (*optional*)                | `string`      | domaine personnalisé que les SDK utilisent pour toutes les requêtes réseau sortantes, couramment utilisé pour le proxying. Le format est `second_level_domain.top_level_domain` (par exemple, `example.com`). Si un format invalide est spécifié, le SDK utilise la valeur Kameleoon par défaut                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `undefined`                                    |
    | requestTimeout (*optional*)               | `number`      | délai d'expiration en *millisecondes* pour toutes les requêtes réseau du SDK ; si le délai est dépassé, la requête échoue immédiatement                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `10_000` (10 secondes)                         |
    | trackingInterval (*optional*)             | `number`      | Spécifie l'intervalle pour les requêtes de suivi, en millisecondes. Tous les visiteurs qui ont été évalués pour un feature flag ou qui avaient des données associées seront inclus dans cette requête de suivi, qui est effectuée une fois par intervalle. La valeur minimale est de `100` ms et la valeur maximale est de `1_000` ms                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `1_000` (1 seconde)                            |

    <Note>
      Le paramètre `domain` est déprécié et sera supprimé dans une future version. Utilisez `cookieDomain` à la place.
    </Note>
  </Tab>

  <Tab title="SDK Version 10">
    | Nom                                       | Type                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Valeur par défaut                              |
    | ----------------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
    | updateInterval (*optional*)               | `number`                | Spécifie l'intervalle de rafraîchissement, en minutes, auquel le SDK récupère la configuration pour les expériences et feature flags actifs. La valeur détermine le temps maximum nécessaire pour propager les modifications, telles que l'activation ou la désactivation de feature flags ou le lancement d'expériences, vers vos serveurs de production. S'il n'est pas spécifié, l'intervalle par défaut est défini à 60 minutes. De plus, nous proposons un [mode streaming](/developer-docs/feature-experimentation/technical-reference/technical-considerations/#streaming-premium-option) qui utilise les server-sent events (SSE) pour pousser automatiquement de nouvelles configurations vers le SDK et appliquer les nouvelles configurations en temps réel, sans aucun délai.                                                 | `60`                                           |
    | environment (*optional*)                  | `Environment \| string` | environnement du feature flag                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `Environment.Production`                       |
    | targetingDataCleanupInterval (*optional*) | `number`                | intervalle en *minutes* pour le nettoyage des données de ciblage ; la valeur minimale est de 1 minute                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `undefined` (aucun nettoyage ne sera effectué) |
    | cookieDomain (*optional*)                 | `string`                | [domaine](#domain-information) auquel appartient le cookie.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `undefined`                                    |
    | networkDomain (*optional*)                | `string`                | domaine personnalisé que les SDK utilisent pour toutes les requêtes réseau sortantes, couramment utilisé pour le proxying. Le format est `second_level_domain.top_level_domain` (par exemple, `example.com`). Si un format invalide est spécifié, le SDK utilise la valeur Kameleoon par défaut                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `undefined`                                    |
    | requestTimeout (*optional*)               | `number`                | délai d'expiration en *millisecondes* pour toutes les requêtes réseau du SDK ; si le délai est dépassé, la requête échoue immédiatement                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `10_000` (10 secondes)                         |
    | trackingInterval (*optional*)             | `number`                | Spécifie l'intervalle pour les requêtes de suivi, en millisecondes. Tous les visiteurs qui ont été évalués pour un feature flag ou qui avaient des données associées seront inclus dans cette requête de suivi, qui est effectuée une fois par intervalle. La valeur minimale est de `1_000` ms et la valeur maximale est de `5_000` ms                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `1_000` (1 seconde)                            |
    | stubMode (*optional*)                     | `boolean`               | Lorsqu'il est défini sur true, le client fonctionnera en mode stub et n'effectuera aucune opération. Dans ce mode, tous les appels de méthode n'exécutent aucune action, garantissant qu'aucune action externe ni effet secondaire ne se produit.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `false`                                        |
    | defaultDataFile (*optional*)              | `string`                | La fonctionnalité `defaultDataFile` garantit que le SDK Kameleoon est toujours **READY** en fournissant une configuration de repli lorsqu'aucun fichier de données en cache n'existe. Les développeurs peuvent précharger une configuration valide en la récupérant depuis `https://sdk-config.kameleoon.eu/v3/<sitecode>` et en la passant en tant que `defaultDataFile` lors de l'initialisation. Lorsqu'un timestamp `dateModified` (en millisecondes) est fourni et qu'il est plus récent que la version en cache, le SDK utilisera le datafile par défaut au lieu de la version en cache. **Si `dateModified` est omis, le datafile par défaut n'est appliqué que lorsqu'aucune version en cache n'existe**. Cela garantit que le SDK dispose toujours d'une configuration valide, qu'elle soit par défaut, en cache ou mise à jour. | `undefined`                                    |

    <Tip>
      **Option 1 (Recommandée) :** Utilisez `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 :** Chaîne JSON brute (échappez les caractères spéciaux)

      ```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>

##### Return value

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

<Note>
  Assurez-vous de ne pas utiliser plusieurs instances de client dans une seule application car cela n'est pas encore entièrement pris en charge et peut écraser la configuration du stockage local et provoquer un comportement inattendu (bugs).
</Note>

### Feature flags and variations

Cette section fournit les méthodes que vous utilisez pour récupérer et gérer les feature flags et variations attribués au visiteur.

#### getVariation()

* 📨 *Envoie des données de suivi à Kameleoon (selon le paramètre `track`)*

Récupère la [`Variation`](#variation) attribuée à un visiteur donné pour un feature flag spécifique.

Cette méthode prend `featureKey` comme argument obligatoire et `track` comme argument optionnel. L'argument `track` est optionnel et vaut `true` par défaut.

Elle renvoie la `Variation` attribuée au visiteur. Si le visiteur n'est associé à aucune règle de feature flag, la méthode renvoie la `Variation` par défaut pour le feature flag donné.

Assurez-vous qu'une gestion d'erreur appropriée est implémentée dans votre code pour gérer les exceptions potentielles.

<Note>
  La variation par défaut fait référence à la variation attribuée à un visiteur lorsqu'il ne correspond à aucune règle de livraison prédéfinie pour un feature flag. En d'autres termes, c'est la variation de repli appliquée à tous les utilisateurs qui ne sont pas ciblés par des règles spécifiques. Elle est représentée comme la variation dans la section "Then, for everyone else..." dans une interface de gestion.
</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

Un objet de type `GetVariationParamsType` avec les propriétés suivantes :

| Nom                      | Type      | Description                                                                                      | Défaut |
| ------------------------ | --------- | ------------------------------------------------------------------------------------------------ | ------ |
| visitorCode (*required*) | `string`  | Identifiant unique du visiteur.                                                                  |        |
| featureKey (*required*)  | `string`  | Clé de la fonctionnalité que vous souhaitez exposer à un visiteur.                               |        |
| track (*optional*)       | `boolean` | Un paramètre optionnel pour activer ou désactiver le suivi de l'évaluation de la fonctionnalité. | `true` |

##### Return value

| Type        | Description                                                                                  |
| ----------- | -------------------------------------------------------------------------------------------- |
| `Variation` | Une [`Variation`](#variation) attribuée à un visiteur donné pour un feature flag spécifique. |

##### Exceptions thrown

| Type                                                  | Description                                                                                                                                                                                                                                                                                             |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel [`initialize`](#initialize).                                                                                                                                                                                           |
| `KameleoonException.VisitorCodeEmpty`                 | Le visitor code est vide.                                                                                                                                                                                                                                                                               |
| `KameleoonException.VisitorCodeMaxLength`             | Le visitor code a dépassé la longueur maximale (255 caractères).                                                                                                                                                                                                                                        |
| `KameleoonException.FeatureFlagConfigurationNotFound` | Exception indiquant que la clé de fonctionnalité demandée n'a pas été trouvée dans la configuration interne du SDK. Cela signifie généralement que le feature flag n'est pas activé dans l'application Kameleoon (mais que le code implémentant la fonctionnalité est déjà déployé dans l'application). |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Exception indiquant que le feature flag est désactivé pour l'environnement actuel du visiteur (par exemple, production, staging ou development).                                                                                                                                                        |

#### getVariations()

* 📨 *Envoie des données de suivi à Kameleoon (selon le paramètre `track`)*
* 🎯 *Events:* [`EventType.Evaluation`](#events-1)

<Info>
  La méthode est obtenue à l'aide du hook `useFeatureFlag`.
</Info>

Récupère une map d'objets [`Variation`](#variation) attribués à un visiteur donné pour tous les feature flags.

Cette méthode itère sur tous les feature flags disponibles et renvoie la `Variation` attribuée pour chaque flag associé au visiteur spécifié. Elle prend `visitorCode` comme argument obligatoire, tandis que `onlyActive` et `track` sont optionnels.

* Si `onlyActive` est défini sur `true`, la méthode `getVariations()` renverra les variations de feature flags à condition que l'utilisateur ne soit pas placé dans la variation `off`.
* Le paramètre `track` contrôle si la méthode suivra ou non les attributions de variations. Par défaut, il est défini sur `true`. S'il est défini sur `false`, le suivi sera désactivé.

La map renvoyée se compose de clés de feature flags comme clés et de leurs `Variation` correspondantes comme valeurs. Si aucune variation n'est attribuée pour un feature flag, la méthode renvoie la `Variation` par défaut pour ce flag.

Une gestion d'erreur appropriée doit être implémentée pour gérer les exceptions potentielles.

<Note>
  La variation par défaut fait référence à la variation attribuée à un visiteur lorsqu'il ne correspond à aucune règle de livraison prédéfinie pour un feature flag. En d'autres termes, c'est la variation de repli appliquée à tous les utilisateurs qui ne sont pas ciblés par des règles spécifiques. Elle est représentée comme la variation dans la section "Then, for everyone else..." dans une interface de gestion.
</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

Un objet de type `GetVariationsParamsType` avec les propriétés suivantes :

| Nom                      | Type      | Description                                                                                                                  | Défaut  |
| ------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------- | ------- |
| visitorCode (*required*) | `string`  | Identifiant unique du visiteur.                                                                                              |         |
| onlyActive (*optional*)  | `boolean` | Un paramètre optionnel indiquant s'il faut renvoyer les variations pour les feature flags actifs (`true`) ou tous (`false`). | `false` |
| track (*optional*)       | `boolean` | Un paramètre optionnel pour activer ou désactiver le suivi de l'évaluation de la fonctionnalité.                             | `true`  |

##### Return value

| Type                     | Description                                                                                                                               |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `Map<string, Variation>` | Map contenant les objets [`Variation`](#variation) attribués des feature flags en utilisant les clés des fonctionnalités correspondantes. |

##### Exceptions thrown

| Type                                      | Description                                                                                                   |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel [`initialize`](#initialize). |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide.                                                                                     |
| `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères).                                              |

#### isFeatureFlagActive()

* 📨 *Envoie des données de suivi à Kameleoon (selon le paramètre `track`)*
* 🎯 *Events:* `EventType.Evaluation`

La méthode `isFeatureFlagActive()`, utilisée avec le hook `useFeatureFlag`, détermine si un visiteur identifié par `visitorCode` a la `featureKey` spécifiée active. Cette méthode vérifie les conditions de ciblage, identifie la variation pour le visiteur et enregistre cette information dans le stockage. De plus, le hook envoie une requête de suivi.

Il existe également une surcharge pour cette méthode qui inclut un paramètre `track`, vous permettant de désactiver le suivi de l'évaluation de la fonctionnalité.

<Note>
  Le visiteur doit être ciblé pour que le feature flag soit actif
</Note>

<Note>
  Kameleoon utilise le suivi pour compter les sessions et les visiteurs lorsque vous appelez certaines méthodes, telles que `isFeatureFlagActive()`, `getVariation()` ou `getVariations()`.

  Utilisez la valeur par défaut `true` pour le paramètre `track` lorsque vous exposez des visiteurs à une variation et avez besoin de les compter. Définissez le paramètre `track` sur `false` uniquement si vous appelez ces méthodes avant d'exposer les visiteurs.

  Par exemple, si vous appelez `getVariations()` pour récupérer toutes les variations avant d'exposer les visiteurs, définissez le paramètre `track` sur `false`. Ce réglage empêche Kameleoon de compter prématurément une session. Vous pouvez ensuite déclencher le suivi plus tard lorsque vous exposez explicitement le visiteur.

  Kameleoon envoie les données de suivi toutes les secondes par défaut. Vous pouvez configurer cet intervalle jusqu'à cinq secondes à l'aide de l'option de configuration de l'intervalle de suivi. Kameleoon regroupe les événements de suivi en une seule session tant que l'intervalle entre les événements est inférieur à 30 minutes. Si plus de 30 minutes s'écoulent entre les événements de suivi, Kameleoon compte les événements comme des sessions distinctes. Une visite apparaît dans vos rapports 30 minutes après le dernier événement enregistré dans la 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>
  La méthode `isFeatureFlagActive()` évalue la variante servie, pas l'état du master flag. Si vous excluez les règles, la méthode utilise l'état par défaut **Then, for everyone else serve**. Si vous sélectionnez **Off** pour cet état par défaut, la méthode renvoie toujours `false` même lorsque le master feature flag est **On**.
</Warning>

##### Arguments

Deux surcharges sont disponibles pour cette méthode :

1. Surcharge à deux paramètres :

<Warning>
  Cette surcharge est dépréciée et sera supprimée dans la prochaine version majeure. Veuillez utiliser la nouvelle surcharge avec un paramètre objet.
</Warning>

| Nom                      | Type     | Description                                                                                 |
| ------------------------ | -------- | ------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur |
| featureKey (*required*)  | `string` | une clé unique pour le feature flag                                                         |

2. Surcharge avec paramètre objet de type `IsFeatureFlagActiveParamsType` :

| Nom                      | Type      | Description                                                                                 | Défaut |
| ------------------------ | --------- | ------------------------------------------------------------------------------------------- | ------ |
| visitorCode (*required*) | `string`  | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur | -      |
| featureKey (*required*)  | `string`  | une clé unique pour le feature flag                                                         | -      |
| track (*optional*)       | `boolean` | un indicateur booléen indiquant s'il faut suivre l'évaluation de la fonctionnalité          | `true` |

##### Return value

| Type      | Description                                                                                       |
| --------- | ------------------------------------------------------------------------------------------------- |
| `boolean` | indicateur de si le feature flag avec `featureKey` est actif pour le visiteur avec `visitorCode`. |

##### Exceptions thrown

| Type                                                  | Description                                                                                              |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize`            |
| `KameleoonException.VisitorCodeMaxLength`             | Le visitor code a dépassé la longueur maximale (255 caractères)                                          |
| `KameleoonException.VisitorCodeEmpty`                 | Le visitor code est vide                                                                                 |
| `KameleoonException.FeatureFlagConfigurationNotFound` | Aucun feature flag n'a été trouvé pour le `featureKey` spécifié                                          |
| `KameleoonException.DataInconsistency`                | Une variation allouée a été trouvée mais il n'y a pas de feature flag avec le `featureKey` correspondant |

***

#### setForcedVariation()

La méthode vous permet d'attribuer programmatiquement une [`Variation`](#variation) spécifique à un utilisateur, en contournant le processus d'évaluation standard. Cela est particulièrement utile pour les expériences contrôlées où la logique d'évaluation habituelle n'est pas requise ou doit être ignorée. Cela peut également être utile dans des scénarios comme le debugging ou les tests personnalisés.

Lorsqu'une variation **forced** est définie, elle remplace la logique d'évaluation en temps réel de Kameleoon. Les processus tels que la segmentation, les conditions de ciblage et les calculs algorithmiques sont ignorés. Pour préserver la segmentation et les conditions de ciblage pendant une expérience, définissez `forceTargeting=false` à la place.

<Info>
  Les variations **simulated** ont toujours la priorité dans l'ordre d'exécution. Si un calcul de variation **simulated** est déclenché, il sera d'abord entièrement traité et complété.
</Info>

Une variation forcée est traitée de la même manière qu'une variation évaluée. Elle est suivie dans les analytiques et stockée dans le contexte utilisateur comme toute variation évaluée standard, garantissant la cohérence des rapports.

La méthode peut générer des exceptions dans certaines conditions (par exemple, paramètres invalides, contexte utilisateur ou problèmes internes). Une gestion appropriée des exceptions est essentielle pour garantir que votre application reste stable et résiliente.

<Warning>
  Il est important de distinguer les variations **forced** des variations **[simulated](#getvisitorcode)** :

  * **Forced variations** : sont spécifiques à une expérience individuelle.
  * **Simulated variations** : affectent le résultat global du **feature flag**.
</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

Un objet de type `SetForcedVariationParametersType` avec les propriétés suivantes :

| Nom                         | Type      | Description                                                                                                                                     | Défaut                                                                                                                                                                           |   |
| --------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| visitorCode (*required*)    | `string`  | Identifiant unique du visiteur.                                                                                                                 |                                                                                                                                                                                  |   |
| experimentId (*required*)   | `number`  | **Experiment Id** qui sera ciblé et sélectionné pendant le processus d'évaluation.                                                              |                                                                                                                                                                                  |   |
| variationKey (*required*)   | \`string  | null\`                                                                                                                                          | **Variation Key** correspondant à une `Variation` qui doit être forcée comme valeur renvoyée pour l'expérience. Si la valeur est `null`, la variation forcée sera réinitialisée. |   |
| forceTargeting (*optional*) | `boolean` | Indique si le ciblage pour l'expérience doit être forcé et ignoré (`true`) ou appliqué comme dans le processus d'évaluation standard (`false`). | `true`                                                                                                                                                                           |   |

##### Exceptions thrown

| Type                                               | Description                                                                                                                                                                                                                                              |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `KameleoonException.VisitorCodeEmpty`              | Le visitor code est vide.                                                                                                                                                                                                                                |
| `KameleoonException.VisitorCodeMaxLength`          | Le visitor code a dépassé la longueur maximale (255 caractères).                                                                                                                                                                                         |
| `KameleoonException.Initialization`                | Indique que le SDK n'est pas encore entièrement initialisé.                                                                                                                                                                                              |
| `KameleoonException.FeatureFlagExperimentNotFound` | Exception indiquant que l'id d'expérience demandé n'a pas été trouvé dans la configuration interne du SDK. C'est généralement normal et signifie que l'expérience correspondant à la règle n'a pas encore été activée du côté de Kameleoon.              |
| `KameleoonException.FeatureFlagVariationNotFound`  | Exception indiquant que la clé (id) de variation demandée n'a pas été trouvée dans la configuration interne du SDK. C'est généralement normal et signifie que l'expérience correspondant à la variation n'a pas encore été activée du côté de Kameleoon. |
| `KameleoonException.StorageRead`                   | Impossible de lire les données du stockage.                                                                                                                                                                                                              |
| `KameleoonException.StorageWrite`                  | Impossible de mettre à jour les données du stockage.                                                                                                                                                                                                     |

<Info>
  Dans la plupart des cas, seule l'erreur de base, `KameleoonException`, doit être gérée, comme démontré dans l'exemple. Cependant, si différents types d'erreurs nécessitent une réponse, gérez chacune séparément en fonction des exigences spécifiques. De plus, pour une fiabilité accrue, les erreurs générales de langage peuvent être gérées en incluant `Error`.
</Info>

#### evaluateAudiences()

* 📨 *Envoie des données de suivi à Kameleoon*

Cette méthode évalue les visiteurs par rapport à tous les segments disponibles dans Audiences Explorer et suit ceux qui correspondent.

`evaluateAudiences()` doit être appelée **après que toutes les données pertinentes du visiteur ont été définies ou mises à jour**, et **juste avant** d'obtenir une variation de fonctionnalité ou de vérifier un feature flag. Cette approche garantit que le visiteur est évalué par rapport aux données les plus actuelles disponibles, permettant une attribution d'audience précise basée sur tous les critères.

Après avoir appelé cette méthode, vous pouvez effectuer une analyse détaillée des performances des segments dans 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

| Nom                      | Type     | Description                     |
| ------------------------ | -------- | ------------------------------- |
| visitorCode (*required*) | `string` | Identifiant unique du visiteur. |

##### Exceptions thrown

| Type                                      | Description                                                                                                   |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel [`initialize`](#initialize). |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide.                                                                                     |
| `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères).                                              |

<Info>
  Dans la plupart des cas, seule l'erreur de base, `KameleoonException`, doit être gérée, comme démontré dans l'exemple. Cependant, si différents types d'erreurs nécessitent une réponse, gérez chacune séparément en fonction des exigences spécifiques. De plus, pour une fiabilité accrue, les erreurs générales de langage peuvent être gérées en incluant `Error`.
</Info>

#### getDataFile()

<Tip>
  Pour évaluer tous les feature flags, utilisez [`getVariations()`](#getvariations). Cette méthode est plus efficace que d'appeler `DataFile` et d'itérer sur les flags avec [`getVariation()`](#getvariation).
</Tip>

Renvoie la configuration actuelle du SDK sous forme d'objet [`DataFile`](#datafile).

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

##### Return value

| Type       | Description                                                  |
| ---------- | ------------------------------------------------------------ |
| `DataFile` | Le [`DataFile`](#datafile) contenant la configuration du SDK |

### Visitor data

Cette section fournit les méthodes que vous utilisez pour gérer les données du visiteur.

#### getVisitorCode()

La méthode `getVisitorCode` collectée à partir du hook `useVisitorCode` obtient un visitor code à partir du cookie du navigateur. Si le visitor code n'existe pas encore, la fonction génère un visitor code aléatoire (ou utilise la valeur `defaultVisitorCode` si vous en avez fourni une) et définit le nouveau visitor code dans un cookie.

<Info>
  La méthode `getVisitorCode()` vous permet de définir des variations **simulated** pour un visiteur. Lorsque les cookies (d'une **request** ou d'un **document**) contiennent la clé `kameleoonSimulationFFData`, le processus d'évaluation standard est contourné. Au lieu de cela, la méthode renvoie directement une [`Variation`](#variation) basée sur les données fournies.

  Vous pouvez appliquer des simulations de deux manières :

  * **Automatiquement (recommandé) :** Si vous utilisez Web Experimentation de Kameleoon ou le SDK en [mode Hybride](/developer-docs/feature-experimentation/get-started/hybrid-experimentation#linking-feature-experiments-with-front-end-tracking-code), le cookie est créé automatiquement lors de la simulation de l'affichage d'une variante à l'aide du [Simulation Panel](/user-manual/experimentation/feature-experimentation/using-the-rollout-planner/validation-and-rollback/using-simulation-mode).
  * **Manuellement :** Définissez le cookie `kameleoonSimulationFFData` manuellement.

  Il est important de distinguer les variations **simulated** des variations **[forced](#setforcedvariation)** :

  * **Simulated variations** : affectent le résultat global du **feature flag**.
  * **Forced variations** : sont spécifiques à une expérience individuelle.

  ⚙️ **Configuration manuelle**

  Veuillez vous assurer que le cookie `kameleoonSimulationFFData` suit ce format :

  * `kameleoonSimulationFFData={"featureKey":{"expId":10,"varId":20}}` : Simule la variation avec `varId` de l'expérience `expId` pour la `featureKey` donnée.
  * `kameleoonSimulationFFData={"featureKey":{"expId":0}}` : Simule la variation par défaut (définie dans la section **Then, for everyone else in Production, serve**) pour la `featureKey` donnée.

  ⚠️ Pour garantir un fonctionnement correct, la valeur du cookie doit être encodée comme un composant URI à l'aide d'une méthode telle 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

| Nom                             | Type     | Description                                                                          |
| ------------------------------- | -------- | ------------------------------------------------------------------------------------ |
| defaultVisitorCode (*optional*) | `string` | visitor code à utiliser dans le cas où il n'y a pas de visitor code dans les cookies |

<Note>
  Si vous ne fournissez pas de `defaultVisitorCode` et qu'aucun visitor code n'est stocké dans un cookie, le visitor code sera généré aléatoirement.
</Note>

##### Return value

| Type     | Description             |
| -------- | ----------------------- |
| `string` | visitor code résultant. |

##### Exceptions thrown

| Type                                      | Description                                |
| ----------------------------------------- | ------------------------------------------ |
| `KameleoonException.VisitorCodeMaxLength` | La longueur du visitor code a été dépassée |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                   |

***

#### addData()

La fonction `addData`, utilisée avec le hook `useData`, collecte les données de ciblage à stocker pour que les autres hooks déterminent si le visiteur actuel est ciblé.

<Note>
  * La fonction `addData()` ne renvoie aucune valeur et n'interagit pas avec les serveurs back-end de Kameleoon par elle-même. Au lieu de cela, toutes les données déclarées sont enregistrées pour une transmission future via la méthode [flush](#flush). Cette approche permet de réduire le nombre d'appels au serveur effectués, car les données sont généralement regroupées en un seul appel au serveur déclenché par l'exécution de [flush](#flush).

  La méthode [trackConversion](#trackconversion) envoie également toutes les données précédemment associées, tout comme [flush](#flush). Il en va de même pour les méthodes [getFeatureFlagVariationKey](#getfeatureflagvariationkey) et [getFeatureVariable](#getfeatureflagvariable) si une règle d'expérimentation est déclenchée.

  * Les données `userAgent` ne seront pas stockées dans le stockage comme les autres données, et elles seront envoyées avec chaque requête de suivi pour le filtrage des bots.

  * Consultez la liste des [conditions prises en charge](#targeting-conditions) pour savoir quels types de données peuvent être utilisés pour le ciblage
</Note>

<Tip>
  Chaque visiteur ne peut avoir qu'une seule instance de données associées pour la plupart des types de données. Cependant, `CustomData` est une exception. Les visiteurs peuvent avoir une instance de `CustomData` associée par `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

| Nom                        | Type                  | Description                                                                                                                                                                                                                                        | Valeur par défaut |
| -------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| visitorCode (*required*)   | `string`              | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères.                                                                                                                                                                   |                   |
| track (*optional*)         | `boolean`             | Spécifie si les données ajoutées sont éligibles pour le suivi. Lorsqu'il est défini sur `false`, les données sont stockées localement et utilisées uniquement pour l'évaluation du ciblage ; elles ne sont pas envoyées à l'API Data de Kameleoon. | `true`            |
| kameleoonData (*optional*) | `KameleoonDataType[]` | nombre d'instances de n'importe quel type de `KameleoonData`, peut être ajouté uniquement dans un tableau ou comme arguments séquentiels                                                                                                           |                   |

<Note>
  * `kameleoonData` est un argument variadique, il peut être passé comme un ou plusieurs arguments (voir l'exemple)

  * L'index ou l'ID des [custom data](/user-manual/assets/custom-data/create-custom-data) peut être trouvé dans votre compte Kameleoon. Il est important de noter que cet index commence à `0`, ce qui signifie que les premières custom data que vous créez pour un site donné se verront attribuer `0` comme ID, et non `1`.
</Note>

##### Exceptions thrown

| Type                                      | Description                                                                                   |
| ----------------------------------------- | --------------------------------------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères)                               |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                                      |
| `KameleoonException.StorageWrite`         | Impossible de mettre à jour les données du stockage                                           |
| `KameleoonException.Initialization`       | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |

<Note>
  Consultez la référence [Data types](#data-types) pour plus de détails sur la façon de gérer différents types de données.
</Note>

***

#### flush()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    La méthode `flush` collectée avec `useData` prend les données Kameleoon associées au visiteur et envoie la requête de suivi des données avec toutes les données précédemment ajoutées à l'aide de [addData](#adddata).

    Si vous ne spécifiez pas de `visitorCode`, le SDK vide toutes ses données stockées vers les serveurs Kameleoon distants. Si des requêtes de suivi précédemment échouées ont été stockées localement pendant le [mode hors ligne](#initialize), le SDK tente d'envoyer les requêtes stockées avant d'exécuter la dernière requête.

    <Note>
      Le paramètre `isUniqueIdentifier` peut être utile dans certains scénarios particuliers, comme lorsque vous ne pouvez pas accéder au `visitorCode` anonyme initialement attribué au visiteur, mais que vous avez accès à un ID interne connecté au visiteur anonyme grâce aux fonctionnalités de fusion de sessions.
    </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

    | Nom                             | Type      | Description                                                                                                                                                                                       | Défaut  |
    | ------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
    | visitorCode (*optional*)        | `string`  | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur ; s'il n'est pas passé, toutes les données seront flushées (envoyées aux serveurs Kameleoon distants) | -       |
    | isUniqueIdentifier (*optional*) | `boolean` | un paramètre optionnel pour spécifier si le visitorCode est un identifiant unique                                                                                                                 | `false` |

    ##### Exceptions thrown

    | Type                                      | Description                                                                                   |
    | ----------------------------------------- | --------------------------------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères)                               |
    | `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                                      |
    | `KameleoonException.Initialization`       | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |
  </Tab>

  <Tab title="SDK Version 10">
    `flush()` prend les données Kameleoon associées au visiteur et planifie l'envoi des données avec la prochaine requête de suivi. L'heure de la prochaine requête de suivi est définie par le paramètre [`trackingInterval`](#configuration-parameters) de la configuration du SDK. Les données du visiteur peuvent être ajoutées à l'aide des méthodes [addData](#adddata) et [getRemoteVisitorData](#getremotevisitordata).

    Si vous ne spécifiez pas de `visitorCode`, le SDK vide toutes ses données stockées vers les serveurs Kameleoon distants. Si des requêtes de suivi précédemment échouées ont été stockées localement pendant le [mode hors ligne](#initialize), le SDK tente d'envoyer les requêtes stockées avant d'exécuter la dernière requête.

    <Tip>
      Si vous devez envoyer des requêtes de suivi immédiatement, utilisez `flushInstant()` — la version asynchrone de `flush` qui renvoie `Promise<void>`. Vous pouvez utiliser `await` lorsque vous avez besoin de garanties de livraison (par exemple, avant la navigation/déchargement de la page), ou l'appeler sans `await` en tant que requête fire-and-forget :

      * `await flushInstant(visitorCode)` envoie les requêtes de suivi immédiatement pour un visiteur spécifique et attend la fin
      * `await flushInstant()` envoie les requêtes de suivi immédiatement pour tous les visiteurs et attend la fin
    </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

    | Nom                      | Type     | Description                                                                                                                                                                            | Défaut |
    | ------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
    | visitorCode (*optional*) | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères ; s'il n'est pas passé, toutes les données seront flushées (envoyées aux serveurs Kameleoon distants). | -      |

    Ou un objet de type FlushParamsType, contenant :

    | Nom                      | Type      | Description                                                                                                                                                                            | Défaut |
    | ------------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
    | visitorCode (*optional*) | `string`  | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères ; s'il n'est pas passé, toutes les données seront flushées (envoyées aux serveurs Kameleoon distants). | -      |
    | instant (*optional*)     | `boolean` | Indicateur booléen indiquant si les données doivent être envoyées instantanément (`true`) ou selon l'intervalle de suivi planifié (`false`).                                           | -      |

    ##### Exceptions thrown

    | Type                                      | Description                                                                                   |
    | ----------------------------------------- | --------------------------------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères)                               |
    | `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                                      |
    | `KameleoonException.Initialization`       | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |
  </Tab>
</Tabs>

***

#### getRemoteData()

La méthode asynchrone `getRemoteData`, collectée avec le hook `useData`, renvoie les données stockées pour un site code spécifié sur un serveur Kameleoon distant.

Par exemple, vous pouvez utiliser cette fonction pour récupérer les préférences des utilisateurs, les données historiques ou toute autre donnée pertinente pour la logique de votre application. En stockant ces données sur nos serveurs hautement scalables à l'aide de notre \[Data API], vous pouvez gérer efficacement d'énormes quantités de données et les récupérer pour chacun de vos visiteurs ou 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

| Nom              | Type     | Description                                                                 |
| ---------------- | -------- | --------------------------------------------------------------------------- |
| key (*required*) | `string` | clé unique à laquelle les données que vous essayez d'obtenir sont associées |

##### Return value

| Type       | Description                                                  |
| ---------- | ------------------------------------------------------------ |
| `JSONType` | promesse avec les données récupérées pour la clé spécifique. |

##### Exceptions thrown

| Type                            | Description                                              |
| ------------------------------- | -------------------------------------------------------- |
| `KameleoonException.RemoteData` | Impossible de récupérer les données du serveur Kameleoon |

***

#### getRemoteVisitorData()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    `getRemoteVisitorData()` est une méthode asynchrone pour récupérer les Kameleoon Visits Data pour le `visitorCode` à partir de l'API Data de Kameleoon. La méthode ajoute les données au stockage pour que d'autres méthodes les utilisent lors de la prise de décisions de ciblage.

    Les données obtenues à l'aide de cette méthode jouent un rôle important lorsque vous souhaitez :

    * utiliser des données collectées sur d'autres appareils.
    * accéder à l'historique d'un utilisateur, comme les pages précédemment visitées lors de visites passées.
    * utiliser des données qui ne sont accessibles que côté client, comme les variables datalayer et les goals qui ne convertissent que sur le front-end.

    Lisez [cet article](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) pour mieux comprendre les cas d'utilisation possibles.

    <Warning>
      Par défaut, `getRemoteVisitorData()` récupère automatiquement les dernières custom data stockées avec `scope=Visitor` et les attache au visiteur sans qu'il soit nécessaire d'appeler la méthode `addData()`. C'est particulièrement utile pour [synchroniser les custom data entre plusieurs appareils](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-data-across-devices).
    </Warning>

    <Note>
      Le paramètre `isUniqueIdentifier` peut être utile dans des scénarios particuliers, comme lorsque vous ne pouvez pas accéder au `visitorCode` anonyme initialement attribué au visiteur, mais que vous avez accès à un ID interne connecté au visiteur anonyme grâce aux fonctionnalités de fusion de sessions.
    </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

    Un objet de type `RemoteVisitorDataParamsType` contenant :

    | Nom                             | Type                     | Description                                                                                                                                                                                | Valeur par défaut                                                                                                           |
    | ------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
    | visitorCode (*required*)        | `string`                 | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur                                                                                                | -                                                                                                                           |
    | shouldAddData (*optional*)      | `boolean`                | indicateur booléen identifiant si les custom data récupérées doivent être ajoutées au stockage comme le fait la méthode `addData`                                                          | `true`                                                                                                                      |
    | filters (*optional*)            | `VisitorDataFiltersType` | filtres pour spécifier quelles données doivent être récupérées des visites ; par défaut, seules les `customData` sont récupérées de la visite actuelle et de la précédente la plus récente | `{ previousVisitAmount: 1, currentVisit: true customData: true }`, les autres paramètres de filtre sont définis sur `false` |
    | isUniqueIdentifier (*optional*) | `boolean`                | paramètre optionnel qui, lorsqu'il est défini sur `true`, spécifie que le visitorCode est un identifiant unique                                                                            | `false`                                                                                                                     |

    ##### Return value

    | Type                  | Description                                          |
    | --------------------- | ---------------------------------------------------- |
    | `KameleoonDataType[]` | promesse avec la liste des Kameleoon Data récupérées |

    ##### Exceptions thrown

    | Type                                      | Description                                                                             |
    | ----------------------------------------- | --------------------------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères)                         |
    | `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                                |
    | `KameleoonException.RemoteData`           | Impossible de récupérer les données du serveur Kameleoon                                |
    | `KameleoonException.VisitAmount`          | Le nombre de visites doit être un nombre entre 1 et 25                                  |
    | `KameleoonException.Initialization`       | La méthode a été exécutée avant que `initialize` ait été terminé pour `kameleoonClient` |

    ##### Using parameters in getRemoteVisitorData()

    La méthode `getRemoteVisitorData()` offre de la flexibilité en vous permettant de définir divers paramètres lors de la récupération des données sur les visiteurs. Que vous cibliez sur la base d'objectifs, d'expériences ou de variations, la même approche s'applique à tous les types de données.

    Par exemple, supposons que vous souhaitiez récupérer des données sur les visiteurs qui ont complété un objectif "Order transaction". Vous pouvez spécifier des paramètres dans la méthode `getRemoteVisitorData()` pour affiner votre ciblage. Par exemple, si vous souhaitez cibler uniquement les utilisateurs qui ont converti sur l'objectif lors de leurs cinq dernières visites, vous pouvez définir le paramètre `previousVisitAmount` sur 5 et `conversions` sur true.

    La flexibilité montrée dans cet exemple n'est pas limitée aux données d'objectifs. Vous pouvez utiliser des paramètres dans la méthode `getRemoteVisitorData()` pour récupérer des données sur une variété de comportements de visiteurs.

    <Note>
      Voici la liste des filtres `VisitorDataFiltersType` disponibles :

      | Nom                              | Type      | Description                                                                                                                                                                                                | Défaut  |
      | -------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
      | previousVisitAmount (*optional*) | `number`  | Nombre de visites précédentes pour lesquelles récupérer les données. Nombre entre `1` et `25`                                                                                                              | `1`     |
      | currentVisit (*optional*)        | `boolean` | Si true, les données de la visite actuelle seront récupérées                                                                                                                                               | `true`  |
      | customData (*optional*)          | `boolean` | Si true, les custom data seront récupérées.                                                                                                                                                                | `true`  |
      | pageViews (*optional*)           | `boolean` | Si true, les données de page seront récupérées.                                                                                                                                                            | `false` |
      | geolocation (*optional*)         | `boolean` | Si true, les données de géolocalisation seront récupérées.                                                                                                                                                 | `false` |
      | device (*optional*)              | `boolean` | Si true, les données d'appareil seront récupérées.                                                                                                                                                         | `false` |
      | browser (*optional*)             | `boolean` | Si true, les données de navigateur seront récupérées.                                                                                                                                                      | `false` |
      | operatingSystem (*optional*)     | `boolean` | Si true, les données du système d'exploitation seront récupérées.                                                                                                                                          | `false` |
      | conversions (*optional*)         | `boolean` | Si true, les données de conversion seront récupérées.                                                                                                                                                      | `false` |
      | experiments (*optional*)         | `boolean` | Si true, les données d'expériences seront récupérées.                                                                                                                                                      | `false` |
      | kcs (*optional*)                 | `boolean` | Si true, le Kameleoon Conversion Score (KCS) sera récupéré. Nécessite le [module complémentaire AI Predictive Targeting](/user-manual/ai-predictive-targeting/target-users-based-on-likelihood-to-convert) | `false` |
    </Note>
  </Tab>

  <Tab title="SDK Version 10">
    `getRemoteVisitorData()` est une méthode asynchrone pour récupérer les Kameleoon Visits Data pour le `visitorCode` à partir de l'API Data de Kameleoon. La méthode ajoute les données au stockage pour que d'autres méthodes les utilisent lors de la prise de décisions de ciblage.

    Les données obtenues à l'aide de cette méthode jouent un rôle important lorsque vous souhaitez :

    * utiliser des données collectées sur d'autres appareils.
    * accéder à l'historique d'un utilisateur, comme les pages précédemment visitées lors de visites passées.
    * utiliser des données qui ne sont accessibles que côté client, comme les variables datalayer et les goals qui ne convertissent que sur le front-end.

    Lisez [cet article](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) pour mieux comprendre les cas d'utilisation possibles.

    <Warning>
      Par défaut, `getRemoteVisitorData()` récupère automatiquement les dernières custom data stockées avec `scope=Visitor` et les attache au visiteur sans qu'il soit nécessaire d'appeler la méthode `addData()`. C'est particulièrement utile pour [synchroniser les custom data entre plusieurs appareils](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-data-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

    Un objet de type `RemoteVisitorDataParamsType` contenant :

    | Nom                        | Type                     | Description                                                                                                                                                                                | Valeur par défaut                                                                                                           |
    | -------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
    | visitorCode (*required*)   | `string`                 | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur                                                                                                | -                                                                                                                           |
    | shouldAddData (*optional*) | `boolean`                | indicateur booléen identifiant si les custom data récupérées doivent être ajoutées au stockage comme le fait la méthode `addData`                                                          | `true`                                                                                                                      |
    | filters (*optional*)       | `VisitorDataFiltersType` | filtres pour spécifier quelles données doivent être récupérées des visites ; par défaut, seules les `customData` sont récupérées de la visite actuelle et de la précédente la plus récente | `{ previousVisitAmount: 1, currentVisit: true customData: true }`, les autres paramètres de filtre sont définis sur `false` |

    ##### Return value

    | Type                  | Description                                          |
    | --------------------- | ---------------------------------------------------- |
    | `KameleoonDataType[]` | promesse avec la liste des Kameleoon Data récupérées |

    ##### Exceptions thrown

    | Type                                      | Description                                                                             |
    | ----------------------------------------- | --------------------------------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères)                         |
    | `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                                |
    | `KameleoonException.RemoteData`           | Impossible de récupérer les données du serveur Kameleoon                                |
    | `KameleoonException.VisitAmount`          | Le nombre de visites doit être un nombre entre 1 et 25                                  |
    | `KameleoonException.Initialization`       | La méthode a été exécutée avant que `initialize` ait été terminé pour `kameleoonClient` |

    ##### Using parameters in getRemoteVisitorData()

    La méthode `getRemoteVisitorData()` offre de la flexibilité en vous permettant de définir divers paramètres lors de la récupération des données sur les visiteurs. Que vous cibliez sur la base d'objectifs, d'expériences ou de variations, la même approche s'applique à tous les types de données.

    Par exemple, supposons que vous souhaitiez récupérer des données sur les visiteurs qui ont complété un objectif "Order transaction". Vous pouvez spécifier des paramètres dans la méthode `getRemoteVisitorData()` pour affiner votre ciblage. Par exemple, si vous souhaitez cibler uniquement les utilisateurs qui ont converti sur l'objectif lors de leurs cinq dernières visites, vous pouvez définir le paramètre `previousVisitAmount` sur 5 et `conversions` sur true.

    La flexibilité montrée dans cet exemple n'est pas limitée aux données d'objectifs. Vous pouvez utiliser des paramètres dans la méthode `getRemoteVisitorData()` pour récupérer des données sur une variété de comportements de visiteurs.

    <Note>
      Voici la liste des filtres `VisitorDataFiltersType` disponibles :

      | Nom                              | Type      | Description                                                                                                                                                                                                                                                                                                                                                    | Défaut  |
      | -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
      | previousVisitAmount (*optional*) | `number`  | Nombre de visites précédentes pour lesquelles récupérer les données. Nombre entre `1` et `25`                                                                                                                                                                                                                                                                  | `1`     |
      | currentVisit (*optional*)        | `boolean` | Si true, les données de la visite actuelle seront récupérées                                                                                                                                                                                                                                                                                                   | `true`  |
      | customData (*optional*)          | `boolean` | Si true, les custom data seront récupérées.                                                                                                                                                                                                                                                                                                                    | `true`  |
      | pageViews (*optional*)           | `boolean` | Si true, les données de page seront récupérées.                                                                                                                                                                                                                                                                                                                | `false` |
      | geolocation (*optional*)         | `boolean` | Si true, les données de géolocalisation seront récupérées.                                                                                                                                                                                                                                                                                                     | `false` |
      | device (*optional*)              | `boolean` | Si true, les données d'appareil seront récupérées.                                                                                                                                                                                                                                                                                                             | `false` |
      | browser (*optional*)             | `boolean` | Si true, les données de navigateur seront récupérées.                                                                                                                                                                                                                                                                                                          | `false` |
      | operatingSystem (*optional*)     | `boolean` | Si true, les données du système d'exploitation seront récupérées.                                                                                                                                                                                                                                                                                              | `false` |
      | conversions (*optional*)         | `boolean` | Si true, les données de conversion seront récupérées.                                                                                                                                                                                                                                                                                                          | `false` |
      | experiments (*optional*)         | `boolean` | Si true, les données d'expériences seront récupérées.                                                                                                                                                                                                                                                                                                          | `false` |
      | kcs (*optional*)                 | `boolean` | Si true, le Kameleoon Conversion Score (KCS) sera récupéré. Nécessite le [module complémentaire AI Predictive Targeting](/user-manual/ai-predictive-targeting/target-users-based-on-likelihood-to-convert)                                                                                                                                                     | `false` |
      | visitorCode (*optional*)         | `boolean` | Si true, Kameleoon récupérera le `visitorCode` de la visite la plus récente et l'utilisera pour la visite actuelle. C'est nécessaire si vous souhaitez vous assurer que le visiteur, identifié par son `visitorCode`, reçoit toujours la même variation entre les visites pour l'[expérimentation cross-device](/developer-docs/cross-device-experimentation). | `true`  |
      | personalization (*optional*)     | `boolean` | Si true, les données de personnalisation seront récupérées. Cela est requis pour la condition de personnalisation                                                                                                                                                                                                                                              | `false` |
      | cbs (*optional*)                 | `boolean` | Si true, les données de score Contextual Bandit seront récupérées.                                                                                                                                                                                                                                                                                             | `false` |
    </Note>
  </Tab>
</Tabs>

***

#### getVisitorWarehouseData()

La méthode asynchrone `getVisitorWarehouseAudience` collectée avec le hook `useData` récupère toutes les données d'audience associées au visiteur dans votre data warehouse à l'aide des `visitorCode` et `warehouseKey` spécifiés. Le `warehouseKey` est généralement votre ID d'utilisateur interne. Le paramètre `customDataIndex` correspond à la custom data Kameleoon utilisée par Kameleoon pour cibler vos visiteurs. Consultez la [documentation sur le ciblage warehouse](/user-manual/integrations/data-warehouses/bigquery/use-bigquery-as-a-source-audience-targeting) pour plus de 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

Objet de paramètres composé de :

| Nom                          | Type     | Description                                                                                                   |
| ---------------------------- | -------- | ------------------------------------------------------------------------------------------------------------- |
| visitorCode (*required*)     | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur                   |
| customDataIndex (*required*) | `number` | nombre représentant l'index de la custom data que vous souhaitez utiliser pour cibler vos Warehouse Audiences |
| warehouseKey (*optional*)    | `string` | clé unique pour identifier les données du warehouse (généralement, votre ID d'utilisateur interne)            |

##### Return value

| Type                          | Description                                                                                                |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `Promise<CustomData \| null>` | promesse contenant CustomData avec les données warehouse associées ou `null` s'il n'y avait pas de données |

##### Exceptions thrown

| Type                                      | Description                                                     |
| ----------------------------------------- | --------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères) |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                        |
| `KameleoonException.RemoteData`           | Impossible de récupérer les données du serveur Kameleoon        |

***

#### setLegalConsent()

La méthode `setLegalConsent`, collectée avec le hook `useVisitorCode`, spécifie si le visiteur a donné son consentement légal à l'utilisation de données personnelles. Définir le paramètre `legalConsent` sur `false` limite les types de données que vous pouvez inclure dans les requêtes de suivi. Cela vous aide à respecter les exigences légales et réglementaires tout en gérant de manière responsable les données des visiteurs. Vous pouvez trouver plus d'informations sur les données personnelles dans la [politique de gestion du consentement](/user-manual/project-management/consent-management-policy).

<Note>
  * Les informations de consentement sont synchronisées entre le moteur Kameleoon (fichier d'application engine.js) et le SDK React. Cette synchronisation signifie qu'une fois le consentement défini sur le moteur ou le SDK, il est automatiquement défini pour les deux. Cette fonctionnalité élimine le besoin de gestion manuelle du consentement et garantit que les SDK fonctionnent conformément aux préférences des utilisateurs.

  Si vous utilisez Kameleoon en mode Hybride, nous vous recommandons de lire la section sur le consentement dans notre [article sur l'expérimentation Hybride](/developer-docs/feature-experimentation/get-started/hybrid-experimentation/#managing-consent-in-hybrid-mode)

  * Lors de la gestion du consentement légal, il est important d'utiliser la méthode [`getVisitorCode`](#getvisitorcode). De plus, `getVisitorCode` n'accepte pas `domain` comme argument. Au lieu de cela, passez-le à la fonction [`createClient`](#createclient).
</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

| Nom                      | Type      | Description                                                                                                                                                                                                              |
| ------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| visitorCode (*required*) | `string`  | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur                                                                                                                              |
| consent (*required*)     | `boolean` | une valeur booléenne représentant le statut du consentement légal. `true` indique que le visiteur a donné son consentement légal, `false` indique que le visiteur n'a jamais fourni, ou a retiré, son consentement légal |

##### Exceptions thrown

| Type                                      | Description                                                                 |
| ----------------------------------------- | --------------------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | La longueur du visitor code a dépassé la longueur maximale (255 caractères) |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                    |

##### Consent revocation behavior

Lorsque vous appelez `setLegalConsent()` avec `consent=false`, le SDK ne supprime pas le cookie `kameleoonVisitorCode`. Au lieu de cela, il arrête de prolonger la date d'expiration du cookie, permettant au cookie de persister jusqu'à son expiration naturelle.

Si vos exigences de conformité demandent la suppression immédiate du fichier de cookie lors de l'opt-out, vous devez le supprimer manuellement à l'aide des méthodes natives de gestion des cookies de votre framework. Le SDK ne supprimera pas le fichier automatiquement.

***

### Goals and third-party analytics

Cette section fournit les méthodes que vous utilisez pour suivre lorsqu'une action d'un visiteur atteint l'un de vos objectifs (une conversion).

#### trackConversion()

<Tabs defaultTabIndex={1}>
  <Tab title="SDK Version 9">
    * \_📨 *Envoie des données de suivi à Kameleoon*

    La fonction `trackConversion()`, utilisée avec le hook `useData`, crée et ajoute des données [`Conversion`](#conversion) au visiteur avec les paramètres spécifiés et exécute `flush()`.

    Utilisez cette méthode pour suivre une conversion pour un [objectif](/user-manual//assets/goals/create-a-goal) spécifique et un utilisateur. Cette méthode nécessite `visitorCode` et `goalId`. De plus, cette méthode accepte également un argument optionnel `revenue`. Le `visitorCode` est généralement identique à celui utilisé lors du déclenchement de l'expérience.

    La méthode `trackConversion()` ne renvoie aucune valeur. Cette méthode est non bloquante car l'appel au serveur est effectué de manière asynchrone.

    Si vous spécifiez un `visitorCode` et définissez `isUniqueIdentifier` sur `true`, la méthode `trackConversion()` l'utilise comme identifiant unique du visiteur, ce qui est utile pour [l'expérimentation cross-device](#cross-device-experimentation) car le SDK lie les données flushées au visiteur associé à l'identifiant spécifié.

    <Note>
      Le paramètre `isUniqueIdentifier` peut également être utile dans d'autres scénarios particuliers, comme lorsque vous ne pouvez pas accéder au `visitorCode` anonyme initialement attribué au visiteur, mais que vous avez accès à un ID interne connecté au visiteur anonyme grâce aux fonctionnalités de fusion de sessions.
    </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

    Objet de paramètres composé de :

    | Nom                             | Type      | Description                                                                        | Défaut  |
    | ------------------------------- | --------- | ---------------------------------------------------------------------------------- | ------- |
    | visitorCode (*required*)        | `string`  | Identifiant unique du visiteur.                                                    |         |
    | goalId (*required*)             | `number`  | ID de l'objectif.                                                                  |         |
    | revenue (*optional*)            | `number`  | Revenu de la conversion.                                                           | `0`     |
    | isUniqueIdentifier (*optional*) | `boolean` | Un paramètre optionnel pour spécifier si le visitorCode est un identifiant unique. | `false` |

    ##### Exceptions thrown

    | Type                                      | Description                                                      |
    | ----------------------------------------- | ---------------------------------------------------------------- |
    | `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères). |
    | `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide.                                        |
    | `KameleoonException.StorageWrite`         | Impossible de mettre à jour les données du stockage.             |
  </Tab>

  <Tab title="SDK Version 10">
    * 📨 *Envoie des données de suivi à Kameleoon*

    La fonction `trackConversion()`, utilisée avec le hook `useData`, crée et ajoute des données [`Conversion`](#conversion) au visiteur avec les paramètres spécifiés et exécute `flush()`.

    Utilisez cette méthode pour suivre une conversion pour un [objectif](/user-manual//assets/goals/create-a-goal) spécifique et un utilisateur. Cette méthode nécessite `visitorCode` et `goalId`. De plus, cette méthode accepte également des arguments optionnels `revenue`, `negative` et `metadata`. Le `visitorCode` est généralement identique à celui utilisé lors du déclenchement de l'expérience.

    La méthode `trackConversion()` ne renvoie aucune valeur. Cette méthode est non bloquante car l'appel au serveur est effectué de manière asynchrone.

    <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

    Objet de paramètres composé de :

    | Nom                      | Type           | Description                                                                                                                                              | Défaut      |
    | ------------------------ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
    | visitorCode (*required*) | `string`       | Identifiant unique du visiteur.                                                                                                                          |             |
    | goalId (*required*)      | `number`       | ID de l'objectif.                                                                                                                                        |             |
    | negative (*optional*)    | `boolean`      | Définit si le revenu est positif ou négatif.                                                                                                             | `false`     |
    | revenue (*optional*)     | `number`       | Revenu de la conversion.                                                                                                                                 | `0`         |
    | metadata (*optional*)    | `CustomData[]` | Métadonnées de la conversion. [Doivent être définies au préalable dans l'application Kameleoon](/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 ces valeurs spécifiées pour la conversion actuelle au lieu de ce qui a été précédemment collecté à l'aide de 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 custom data 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` | Le visitor code a dépassé la longueur maximale (255 caractères). |
    | `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide.                                        |
    | `KameleoonException.StorageWrite`         | Impossible de mettre à jour les données du stockage.             |
  </Tab>
</Tabs>

***

#### getEngineTrackingCode()

Kameleoon s'intègre à plusieurs solutions d'analytique, notamment Mixpanel, Google Analytics 4 et Segment. Pour suivre correctement les expériences côté serveur, appelez la méthode `getEngineTrackingCode()` après que le visiteur a déclenché une expérience. Le SDK renvoie les commandes de la file d'attente JavaScript pour les expériences que le visiteur a déclenchées au cours des cinq dernières secondes. Lorsque vous insérez ce code dans la page, Engine.js traite les commandes et envoie les événements d'exposition via l'intégration analytique active.

Reportez-vous à l'[expérimentation hybride](/developer-docs/feature-experimentation/get-started/hybrid-experimentation) pour plus d'informations sur l'implémentation de 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>
  * Pour utiliser cette fonctionnalité, implémentez à la fois le SDK React et Kameleoon [Engine.js](/developer-docs/web-experimentation/implementation-and-deployment/standard-implementation). Comme Engine.js est utilisé uniquement pour le suivi dans ce flux, vous pouvez installer le tag asynchrone avant la balise fermante `</body>`.

  * Vous pouvez insérer le code de suivi renvoyé directement dans une balise HTML `<script>`.

  ```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` et `234567` sont des IDs d'expérience, et `7890` et `8901` sont des IDs de variation. Dans votre implémentation, le SDK génère ces valeurs dans le code de suivi renvoyé.
</Note>

##### Arguments

| Nom                      | Type     | Description                     |
| ------------------------ | -------- | ------------------------------- |
| visitorCode (*required*) | `string` | Identifiant unique du visiteur. |

##### Return value

| Type     | Description                             |
| -------- | --------------------------------------- |
| `string` | Code JavaScript à insérer dans la page. |

##### Exceptions thrown

| Type                                      | Description                                                     |
| ----------------------------------------- | --------------------------------------------------------------- |
| `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères) |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                        |

***

### Events

Cette section fournit les méthodes que vous utilisez pour gérer les événements.

<Tabs defaultTabIndex={0}>
  <Tab title="SDK Version 10">
    #### onEvent()

    La méthode `onEvent`, collectée avec le hook `useInitialize`, déclenche un callback lorsqu'un événement spécifique est déclenché. La fonction callback a accès aux données associées à l'événement. Les méthodes du SDK dans cette documentation indiquent quels types d'événements elles peuvent déclencher, le cas échéant.

    <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 ne pouvez attribuer qu'un seul callback à chaque `EventType`.
    </Note>

    ##### Events

    Les événements sont définis dans l'enum `EventType`. Selon le type d'événement, le paramètre `eventData` aura un type différent.

    | Type                            | Type de `eventData`                | Description                                                                                                                                 |
    | ------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
    | `EventType.Evaluation`          | `EvaluationEventDataType`          | Déclenché lorsque le SDK évalue n'importe quelle variation pour un feature flag. Il est déclenché indépendamment de la variation résultante |
    | `EventType.ConfigurationUpdate` | `ConfigurationUpdateEventDataType` | Déclenché lorsque le SDK reçoit une mise à jour de configuration du serveur (lors de l'utilisation du streaming en temps réel)              |

    ##### Arguments

    | Nom                   | Type                                            | Description                                                                                                             |
    | --------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
    | event (*required*)    | `EventType`                                     | un type d'événement auquel associer l'action callback                                                                   |
    | callback (*required*) | `(eventData: EventDataType<EventType>) => void` | une fonction callback avec le paramètre `eventData` qui sera appelée lorsqu'une mise à jour de configuration se produit |

    ##### Exceptions thrown

    | Type                                | Description                                                                                   |
    | ----------------------------------- | --------------------------------------------------------------------------------------------- |
    | `KameleoonException.Initialization` | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |

    ***

    ##### Sending exposure events to external tools

    Kameleoon offre des intégrations natives avec diverses solutions d'analytique et de CDP, telles que [Mixpanel, Google Analytics 4, Segment...](/user-manual/integrations/integrations-overview). Pour garantir que vous pouvez suivre et analyser vos expériences côté serveur, Kameleoon fournit une méthode `getEngineTrackingCode()` qui renvoie le code JavaScript à insérer dans votre page pour envoyer automatiquement les événements d'exposition à la solution d'analyse que vous utilisez. Le SDK construit un code de suivi pour votre solution d'analyse active en fonction des expériences que le visiteur a déclenchées au cours des 5 dernières secondes.
    Pour plus d'informations sur l'expérimentation hybride, veuillez consulter cette [documentation](/developer-docs/feature-experimentation/get-started/hybrid-experimentation).

    <Note>
      Pour bénéficier de cette fonctionnalité, vous devrez implémenter à la fois le SDK React et notre tag JavaScript Kameleoon. Nous vous recommandons d'implémenter le \[tag asynchrone Kameleoon], que vous pouvez installer avant votre balise fermante `<body>` dans votre page HTML, car il ne sera utilisé qu'à des fins de suivi.
    </Note>
  </Tab>
</Tabs>

### Data types

Les types de Data Kameleoon sont des classes d'aide utilisées pour stocker des données dans le stockage sous des formes prédéfinies.
Lors de l'exécution de [flush](#flush), le SDK collecte toutes les données et les envoie avec la requête de suivi.

Les données disponibles dans le SDK ne sont pas disponibles pour le ciblage et le reporting dans l'application Kameleoon tant que vous n'ajoutez pas les données. Par exemple, en utilisant la méthode `addData()`.
Voir [use visit history to target users](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) pour plus d'informations.

<Note>
  Si vous utilisez le mode hybride, vous pouvez appeler `getRemoteVisitorData()` pour remplir automatiquement toutes les données que Kameleoon a précédemment collectées.
</Note>

#### Browser

<Note>
  Depuis le SDK React `10.11.0`, `Browser` est automatiquement détecté en fonction de la chaîne `User-Agent`. Cependant, vous pouvez toujours le remplacer manuellement si nécessaire.
</Note>

Browser contient les informations du navigateur.

<Note>
  Chaque visiteur ne peut avoir qu'un seul `Browser`. Ajouter un deuxième `Browser` écrase le premier.
</Note>

| Nom                  | Type          | Description                                                                                                 |
| -------------------- | ------------- | ----------------------------------------------------------------------------------------------------------- |
| browser (*required*) | `BrowserType` | type de navigateur prédéfini (`Chrome`, `InternetExplorer`, `Firefox`, `Safari`, `Opera`, `Other`)          |
| version (*optional*) | `number`      | version du navigateur, le nombre à virgule flottante représente la version majeure et mineure du navigateur |

<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

Les données `UniqueIdentifier` sont utilisées comme marqueur pour l'identification unique du visiteur.

Si vous ajoutez `UniqueIdentifier` pour un visiteur, le `visitorCode` est utilisé comme identifiant unique du visiteur, ce qui est utile pour [l'expérimentation cross-device](/developer-docs/cross-device-experimentation). Associer un `UniqueIdentifier` à un visiteur indique au SDK que le visiteur est lié à un autre visiteur.

L'`UniqueIdentifier` peut également être utile dans d'autres scénarios particuliers, comme lorsque vous ne pouvez pas accéder au `visitorCode` anonyme initialement attribué au visiteur, mais que vous avez accès à un ID interne connecté au visiteur anonyme grâce aux fonctionnalités de fusion de sessions.

<Note>
  Chaque visiteur ne peut avoir qu'un seul `UniqueIdentifier`. Ajouter un autre `UniqueIdentifier` écrase le premier.
</Note>

| Nom                | Type      | Description                                                                                                                                          |
| ------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| value (*required*) | `boolean` | valeur qui spécifie si le visiteur est associé à un autre visiteur ; fournir `false` impliquera que le visiteur n'est associé à aucun autre 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

L'ensemble de données `Conversion` stocké ici peut être utilisé pour filtrer les rapports d'expériences et de personnalisations par n'importe quel objectif qui lui est associé.

<Tip>
  * Chaque visiteur peut avoir plusieurs objets `Conversion`.
  * Vous pouvez trouver le `goalId` dans l'application Kameleoon.
</Tip>

`ConversionParametersType` conversionParameters - un objet avec les paramètres de conversion décrits ci-dessous

| Nom                   | Type           | Description                                  | Défaut      |
| --------------------- | -------------- | -------------------------------------------- | ----------- |
| goalId (*required*)   | `number`       | ID de l'objectif.                            |             |
| revenue (*optional*)  | `float`        | Revenu de la conversion                      | `0`         |
| negative (*optional*) | `boolean`      | Définit si le revenu est positif ou négatif. | `false`     |
| metadata (*optional*) | `CustomData[]` | Métadonnées de la 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` contient des informations sur le cookie stocké sur l'appareil du visiteur.

<Note>
  * En général, le SDK React tentera d'utiliser un cookie `localStorage` pour les conditions. Si ce n'est pas possible, le SDK peut utiliser les données `Cookie` comme alternative.

  * Chaque visiteur ne peut avoir qu'un seul `Cookie`. Ajouter un deuxième `Cookie` écrase le premier.
</Note>

| Nom                 | Type           | Description                                                               |
| ------------------- | -------------- | ------------------------------------------------------------------------- |
| cookie (*required*) | `CookieType[]` | Une liste d'objets `CookieType` composés de clés et de valeurs de cookies |

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

##### Methods

Les données `Cookie` ont une méthode utilitaire statique `fromString` que vous pouvez utiliser pour créer un cookie instantanément en analysant une chaîne qui contient des données de cookie valides.
La méthode accepte une `string` en paramètre et renvoie une instance `Cookie` initialisée.

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

#### GeolocationData

`GeolocationData` contient les détails de géolocalisation du visiteur

<Note>
  Chaque visiteur ne peut avoir qu'un seul `GeolocationData`. Ajouter un deuxième `GeolocationData` écrase le premier.
</Note>

Un paramètre objet de type `GeolocationInfoType` contenant les champs suivants :

| Nom                      | Type               | Description                                                                                                                               |
| ------------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| country (*required*)     | `string`           | Le pays du visiteur                                                                                                                       |
| region (*optional*)      | `string`           | La région du visiteur                                                                                                                     |
| city (*optional*)        | `string`           | La ville du visiteur                                                                                                                      |
| postalCode (*optional*)  | `string`           | Le code postal du visiteur                                                                                                                |
| coordinates (*optional*) | `[number, number]` | Tuple tableau de coordonnées de deux valeurs de position (longitude et latitude). Le nombre de coordonnées représente des degrés décimaux |

<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

Pour conserver les custom data pour les visites futures, le SDK transmet `CustomData` avec un scope `Visitor` lors de la prochaine requête de suivi. Vous pouvez configurer le scope dans les paramètres des données sur le [dashboard custom data](https://app.kameleoon.com/customData/dashboard).

`CustomData` vous permet d'associer facilement n'importe quel type de données à chaque visiteur. Ces données peuvent ensuite être utilisées comme condition de ciblage dans les [segments](/user-manual/assets/segments/create-a-segment/) ou comme filtre ou breakdown dans les rapports d'expériences.

Pour plus d'informations sur les custom data, veuillez consulter cet [article](/developer-docs/custom-data).

| Nom                     | Type              | Description                                                                                                                                                                                                      | Défaut |
| ----------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| index/name (*required*) | `number`/`string` | Index ou Nom de la custom data. **`index` ou `name` doit être fourni** pour identifier les données.                                                                                                              |        |
| overwrite (*optional*)  | `boolean`         | Indicateur pour contrôler explicitement comment les valeurs sont stockées et apparaissent dans les rapports. [Voir plus](/developer-docs/custom-data#default-logic-when-overwrite-parameter-is-false-or-omitted) | `true` |
| value (*required*)      | `string[]`        | La valeur de la custom data. Elle doit être convertie en chaîne pour correspondre au type `string`. *Note :* value est variadique.                                                                               |        |

<Note>
  * Chaque visiteur n'est autorisé qu'à un seul `CustomData` pour chaque `index` unique. Ajouter un autre `CustomData` avec le même `index` remplacera l'existant.

  * L'« index » de la custom data peut être trouvé dans le [dashboard Custom Data](/user-manual/assets/custom-data/manage-custom-data) sous la colonne « INDEX ».

  * Pour empêcher le SDK d'envoyer des données avec l'index sélectionné aux serveurs Kameleoon pour des raisons de confidentialité, activez l'option : **Use this data only locally for targeting purposes** lors de la création de la custom data.

  * Ajouter une instance `CustomData` créée avec un nom alors que l'instance SDK n'est pas initialisée ou que le nom n'est pas enregistré, entraînera l'ignorance des données.
</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>
  Depuis le SDK React `10.11.0`, `Device` est automatiquement détecté en fonction de la chaîne `User-Agent`. Cependant, vous pouvez toujours le remplacer manuellement si nécessaire.

  **React Native :** La prise en charge de cette fonctionnalité est actuellement expérimentale et peut nécessiter des ajustements pour fonctionner correctement. Dans React Native, le `Device` est automatiquement détecté en fonction du `DPI` de `react-native.Dimensions`.
</Note>

Device contient des informations sur votre appareil.

<Note>
  Chaque visiteur ne peut avoir qu'un seul `Device`. Ajouter un deuxième `Device` écrase le premier.
</Note>

| Nom                     | Type         | Description                                                            |
| ----------------------- | ------------ | ---------------------------------------------------------------------- |
| deviceType (*required*) | `DeviceType` | types possibles pour le type d'appareil (`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>
  Depuis le SDK React `10.11.0`, `OperatingSystem` est automatiquement détecté en fonction de la chaîne `User-Agent`. Cependant, vous pouvez toujours le remplacer manuellement si nécessaire.

  **React Native :** La prise en charge de cette fonctionnalité est actuellement expérimentale et peut nécessiter des ajustements pour fonctionner correctement. Dans React Native, l'`OperatingSystem` est automatiquement détecté en fonction de `react-native.Platform`.
</Note>

`OperatingSystem` contient les informations du système d'exploitation du visiteur.

<Note>
  Chaque visiteur ne peut avoir qu'un seul `OperatingSystem`. Ajouter un deuxième `OperatingSystem` écrase le précédent.
</Note>

| Nom                          | Type                  | Description                                                                                            |
| ---------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------ |
| operatingSystem (*required*) | `OperatingSystemType` | types possibles pour le type d'appareil : `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>
  Depuis le SDK React `10.11.0`, `PageView` est automatiquement détecté en fonction de `window.location?.href` et `document.title`. Cependant, vous pouvez toujours le remplacer manuellement si nécessaire.

  **React Native :** La prise en charge de cette fonctionnalité est actuellement expérimentale et peut nécessiter des ajustements pour fonctionner correctement.
</Note>

PageView contient des informations sur votre page web.

<Note>
  Chaque visiteur peut avoir un `PageView` par URL unique. Ajouter un `PageView` avec la même URL qu'un existant informera le SDK que le visiteur a revisité la page
</Note>

`PageViewParametersType` pageViewParameters - un objet avec les paramètres de vue de page décrits ci-dessous

| Nom                     | Type       | Description                                                                                     |
| ----------------------- | ---------- | ----------------------------------------------------------------------------------------------- |
| urlAddress (*required*) | `string`   | adresse url de la page à suivre                                                                 |
| title (*required*)      | `string`   | titre de la page web                                                                            |
| referrer (*optional*)   | `number[]` | un paramètre optionnel contenant une liste d'indices de référents, n'a pas de 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

Stocke les informations sur le user-agent du visiteur. Les expériences côté serveur sont plus vulnérables au **trafic des bots** que les expériences côté client. Pour résoudre ce problème, Kameleoon utilise la liste IAB/ABC International Spiders and Bots List pour identifier les bots et spiders connus. Kameleoon utilise également le champ `UserAgent` pour filtrer les bots et autre trafic indésirable qui pourrait autrement fausser vos métriques de conversion. Pour plus de détails, consultez l'article d'aide sur le [filtrage des bots](/user-manual/faq#how-does-kameleoon-filter-bot-traffic-from-my-results).

Si vous utilisez des bots internes, nous vous suggérons de passer la valeur **curl/8.0** du userAgent pour les exclure de nos analytiques.

<Note>
  Un visiteur ne peut avoir qu'un seul `UserAgent`. Ajouter un deuxième `UserAgent` écrase le premier.
</Note>

| Nom                | Type     | Description                      |
| ------------------ | -------- | -------------------------------- |
| value (*required*) | `string` | valeur utilisée pour comparaison |

<Warning>
  Les expériences côté serveur sont plus vulnérables au **trafic des bots** que les expériences côté client. Pour résoudre ce problème, Kameleoon utilise la liste IAB/ABC International Spiders and Bots List pour identifier les bots et spiders connus. Nous vous recommandons de passer le user agent à filtrer par Kameleoon lors de l'exécution d'expériences côté serveur pour chaque visiteur naviguant sur votre site Web, afin d'éviter de compter les bots dans vos analytiques.

  Si vous utilisez des bots internes, nous vous suggérons de passer la valeur **curl/8.0** du userAgent pour les exclure de nos analytiques.
</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` représente le numéro de version sémantique de votre application.

<Tip>
  Un **visiteur** ne peut avoir qu'un seul `ApplicationVersion`. Ajouter une deuxième instance écrasera la première.
</Tip>

| Nom                  | Type     | Description                                                                                                                                                     |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| version (*optional*) | `string` | La version de l'application mobile. Ce champ doit suivre le versionnement sémantique. Les formats acceptés sont `major`, `major.minor`, ou `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

#### DataFile

Le `DataFile` contient les détails de configuration du SDK.

Il peut être étendu avec des informations supplémentaires si nécessaire pour les clients. Si vous avez besoin de plus de détails, veuillez contacter votre Customer Success Manager.

| Nom          | Type                       | Description                                                                                        |
| ------------ | -------------------------- | -------------------------------------------------------------------------------------------------- |
| featureFlags | `Map<string, FeatureFlag>` | Une map d'objets [`FeatureFlag`](#featureflag), indexée par les clés de feature flag.              |
| dateModified | `number`                   | Le timestamp (en millisecondes) indiquant quand le `DataFile` a été modifié pour la dernière fois. |

<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

Le `FeatureFlag` représente un ensemble de propriétés qui définissent un feature flag lui-même — par exemple, ses [`Variations`](#variation), [`Rules`](#rule), statut d'environnement et autres détails associés.

Il peut être étendu avec des informations supplémentaires si nécessaire pour les clients. Si vous avez besoin de plus de détails, veuillez contacter votre Customer Success Manager.

| Nom                 | Type                     | Description                                                        |
| ------------------- | ------------------------ | ------------------------------------------------------------------ |
| environmentEnabled  | `boolean`                | Indique si le feature flag est activé dans l'environnement actuel. |
| defaultVariationKey | `string`                 | La clé de la variation par défaut associée au feature flag.        |
| variations          | `Map<string, Variation>` | Une map d'objets `Variation`, indexée par les clés de variation.   |
| rules               | `Rule[]`                 | Une liste d'objets `Rule`                                          |

<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

La `Rule` représente un ensemble de propriétés qui définissent une règle elle-même — par exemple, ses [`Variations`](#variation).

Elle peut être étendue avec des informations supplémentaires si nécessaire pour les clients. Si vous avez besoin de plus de détails, veuillez contacter votre Customer Success Manager.

| Nom        | Type                     | Description                                                      |
| ---------- | ------------------------ | ---------------------------------------------------------------- |
| variations | `Map<string, Variation>` | Une map d'objets `Variation`, indexée par les clés de variation. |

<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` contient des informations sur la variation attribuée au visiteur (ou la variation par défaut, si aucune attribution spécifique n'existe).

| Nom          | Type                    | Description                                                                                                 |
| ------------ | ----------------------- | ----------------------------------------------------------------------------------------------------------- |
| name         | `string`                | nom de la variation.                                                                                        |
| key          | `string`                | clé de la variation.                                                                                        |
| id           | `number` or `null`      | id de la variation ou `null` si le visiteur a atterri sur la variation par défaut.                          |
| experimentId | `number` or `null`      | id de l'expérience ou `null` si le visiteur a atterri sur la variation par défaut.                          |
| variables    | `Map<string, Variable>` | map des variables pour la variation, où la clé est la clé de la variable et la valeur est l'objet variable. |

<Note>
  * Assurez-vous que votre code gère le cas où `id` ou `experimentId` peut être `null`, indiquant une variation par défaut.
  * La map `variables` peut être vide si aucune variable n'est associée à la 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` contient des informations sur une variable associée à la variation attribuée.

| Nom   | Type     | Description                                                                                                                                     |
| ----- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| key   | `string` | La clé unique identifiant la variable.                                                                                                          |
| type  | `string` | Le type de la variable. Valeurs possibles : **BOOLEAN**, **NUMBER**, **STRING**, **JSON**, **JS**, **CSS**.                                     |
| value | `any`    | La valeur de la variable, qui peut être de l'un des types suivants : **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>
  Ces méthodes sont dépréciées et seront supprimées dans la prochaine mise à jour majeure.
</Warning>

#### getFeatureFlagVariationKey()

* 📨 *Envoie des données de suivi à Kameleoon*
* 🎯 *Events:* `EventType.Evaluation`

<Note>
  Utilisez la méthode [`getVariation`](#getvariation).
</Note>

La méthode `getFeatureFlagVariationKey()`, qui est utilisée avec le hook `useFeatureFlag`, récupère la clé de variation pour un visiteur identifié par son `visitorCode`. Ce processus inclut la vérification des critères de ciblage, l'identification de la variation appropriée attribuée au visiteur, le stockage de ces informations, et l'envoi d'une requête de suivi.

<Note>
  Si un utilisateur n'a jamais été associé à un feature flag, le SDK renverra aléatoirement une clé de variation selon les règles de ce feature flag. Si l'utilisateur est déjà lié au feature flag, le SDK identifiera la clé de variation précédemment attribuée. Si l'utilisateur ne correspond à aucune des règles spécifiées, le SDK renverra la valeur par défaut définie dans les règles de livraison du feature flag de Kameleoon. Il est important de noter que la valeur par défaut peut ne pas toujours être une clé de variation ; il peut également s'agir d'une valeur booléenne ou d'un autre type de données, selon la configuration du feature flag.
</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

| Nom                      | Type     | Description                                                                                 |
| ------------------------ | -------- | ------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur |
| featureKey (*required*)  | `string` | une clé unique pour le feature flag                                                         |

##### Return value

| Type     | Description                                                                                                |
| -------- | ---------------------------------------------------------------------------------------------------------- |
| `string` | une chaîne contenant la clé de variable pour la variation de feature flag allouée pour le visiteur fourni. |

##### Exceptions thrown

| Type                                                  | Description                                                                             |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | La méthode a été exécutée avant que `initialize` ait été terminé pour `kameleoonClient` |
| `KameleoonException.VisitorCodeMaxLength`             | Le visitor code a dépassé la longueur maximale (255 caractères)                         |
| `KameleoonException.VisitorCodeEmpty`                 | Le visitor code est vide                                                                |
| `KameleoonException.FeatureFlagConfigurationNotFound` | Aucun feature flag n'a été trouvé pour le `featureKey` spécifié                         |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Le feature flag est désactivé pour l'environnement actuel                               |

#### getVisitorFeatureFlags()

* 🚫 *N'envoie pas de données de suivi à Kameleoon*
* 🎯 *Events:* `EventType.Evaluation` (pour chaque feature flag)

<Note>
  Utilisez la méthode [`getVariations`](#getvariations).
</Note>

La méthode `getVisitorFeatureFlags`, utilisée avec le hook `useFeatureFlag`, renvoie une liste de feature flags *actifs* qui ciblent le visiteur associé au `visitorCode` (le visiteur doit avoir l'une des variations allouées).

<Warning>
  Cette méthode ne collecte que les feature flags actuellement actifs pour le visiteur. Par conséquent, elle n'inclut aucun feature flag pour lequel le visiteur est attribué à la variation « off » (par défaut ou contrôle). Si vous devez récupérer tous les feature flags du visiteur, utilisez plutôt `getFeatureFlags`.

  Par exemple :

  ```ts theme={null}
  // -- `getVisitorFeatureFlags` doesn't 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);
  });
  ```

  Pour les cas où vous avez besoin de tous les feature flags du visiteur, utilisez plutôt [`getFeatureFlags`](#getfeatureflags) :

  ```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

| Nom                      | Type     | Description                                                                                 |
| ------------------------ | -------- | ------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur |

##### Return value

| Type                | Description                                                                    |
| ------------------- | ------------------------------------------------------------------------------ |
| `FeatureFlagType[]` | liste de feature flags, chaque élément de feature flag contient `id` et `key`. |

##### Exceptions thrown

| Type                                      | Description                                                                                   |
| ----------------------------------------- | --------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |
| `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale (255 caractères)                               |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                                      |
| `KameleoonException.StorageRead`          | Erreur lors de la lecture des données du stockage                                             |

***

#### getActiveFeatureFlags()

* 🚫 *N'envoie pas de données de suivi à Kameleoon*
* 🎯 *Events:* `EventType.Evaluation` (pour chaque feature flag)

<Note>
  Utilisez la méthode [`getVariations`](#getvariations).
</Note>

La méthode `getActiveFeatureFlags`, collectée avec le hook `useFeatureFlag`, renvoie une `Map`, où la clé est la clé de fonctionnalité et la valeur est l'information détaillée sur la variation du visiteur et ses 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 ne collecte que les feature flags *actifs* du visiteur. Cela signifie que le résultat exclut tous les feature flags pour lesquels le visiteur est attribué à la variation `off` (par défaut ou contrôle). Lorsque vous avez besoin de tous les feature flags du visiteur pour itérer dessus, utilisez plutôt `getFeatureFlags`.

  Consultez la section *CAUTION* de la méthode [getVisitorFeatureFlags](#getvisitorfeatureflags) pour plus de détails.
</Warning>

##### Arguments

| Nom                      | Type     | Description                                                                                 |
| ------------------------ | -------- | ------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur |

##### Return value

| Type                                  | Description                                                                                                                                             |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Map<string, KameleoonVariationType>` | une map de feature flags, où la clé est la clé de fonctionnalité et la valeur est l'information détaillée sur la variation du visiteur et ses variables |

##### Exceptions thrown

| Type                                      | Description                                                                                   |
| ----------------------------------------- | --------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`       | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |
| `KameleoonException.VisitorCodeMaxLength` | Le visitor code a dépassé la longueur maximale de 255 caractères                              |
| `KameleoonException.VisitorCodeEmpty`     | Le visitor code est vide                                                                      |
| `KameleoonException.StorageRead`          | Erreur lors de la lecture des données du stockage                                             |
| `KameleoonException.NumberParse`          | Impossible d'analyser la valeur Number                                                        |
| `KameleoonException.JSONParse`            | Impossible d'analyser la valeur JSON                                                          |

***

#### getFeatureFlagVariable()

* 📨 *Envoie des données de suivi à Kameleoon*
* 🎯 *Events:* `EventType.Evaluation`

<Note>
  Utilisez la méthode [`getVariation`](#getvariation).
</Note>

La méthode `getFeatureFlagVariable`, collectée avec le hook `useFeatureFlag`, renvoie une variable pour le visiteur sous `visitorCode` dans le feature flag trouvé ; cela inclut la vérification du ciblage, la recherche de la variation correspondante exposée au visiteur et son enregistrement dans le stockage en même temps que l'envoi de la requête de suivi.

<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

Objet de paramètres de type `GetFeatureFlagVariableParamsType` contenant les champs suivants :

| Nom                      | Type     | Description                                                                                                                   |
| ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur                                   |
| featureKey (*required*)  | `string` | une clé unique pour le feature flag                                                                                           |
| variableKey (*required*) | `string` | clé de la variable à trouver pour un feature flag avec le `featureKey` spécifié, peut être trouvé sur la plateforme Kameleoon |

##### Return value

| Type                      | Description                                                                                                                                                                                                                     |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FeatureFlagVariableType` | un objet variable contenant les champs `type` et `value`. Vous pouvez vérifier le champ `type` par rapport à l'enum `VariableType`. Par exemple, si le `type` est `VariableType.BOOLEAN`, alors `value` sera de type `boolean`. |

##### Exceptions thrown

| Type                                                  | Description                                                                                         |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | La méthode a été exécutée avant que `initialize` ait été terminé pour `kameleoonClient`             |
| `KameleoonException.VisitorCodeMaxLength`             | Le visitor code a dépassé la longueur maximale (255 caractères)                                     |
| `KameleoonException.VisitorCodeEmpty`                 | Le visitor code est vide                                                                            |
| `KameleoonException.FeatureFlagConfigurationNotFound` | Aucun feature flag n'a été trouvé pour le `featureKey` spécifié                                     |
| `KameleoonException.FeatureFlagVariableNotFound`      | Aucune variable de fonctionnalité n'a été trouvée pour les `visitorCode` et `variableKey` spécifiés |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Le feature flag est désactivé pour l'environnement actuel                                           |
| `KameleoonException.JSONParse`                        | Impossible d'analyser la valeur JSON                                                                |
| `KameleoonException.NumberParse`                      | Impossible d'analyser la valeur Number                                                              |

#### getFeatureFlagVariables()

* 📨 *Envoie des données de suivi à Kameleoon*
* 🎯 *Events:* `EventType.Evaluation` (pour chaque feature flag)

<Note>
  Utilisez la méthode [`getVariations`](#getvariations).
</Note>

La méthode `getFeatureFlagVariables`, collectée avec le hook `useFeatureFlag`, renvoie une liste de variables pour le visiteur sous `visitorCode` dans le feature flag trouvé ; cela inclut la vérification du ciblage, la recherche de la variation correspondante exposée au visiteur et son enregistrement dans le stockage en même temps que l'envoi de la requête de suivi.

<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

| Nom                      | Type     | Description                                                                                 |
| ------------------------ | -------- | ------------------------------------------------------------------------------------------- |
| visitorCode (*required*) | `string` | chaîne d'identification unique du visiteur, ne peut pas dépasser 255 caractères de longueur |
| featureKey (*required*)  | `string` | une clé unique pour le feature flag                                                         |

##### Return value

| Type                          | Description                                                                                                                                                                                                                                      |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `FeatureVariableResultType[]` | une liste d'objets variable contenant les champs `key`, `type` et `value`. Vous pouvez vérifier le champ `type` par rapport à l'enum `VariableType`. Par exemple, si le `type` est `VariableType.BOOLEAN`, alors `value` sera de type `boolean`. |

##### Exceptions thrown

| Type                                                  | Description                                                                                          |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization`                   | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize`        |
| `KameleoonException.VisitorCodeMaxLength`             | Le visitor code a dépassé la longueur maximale (255 caractères)                                      |
| `KameleoonException.VisitorCodeEmpty`                 | Le visitor code est vide                                                                             |
| `KameleoonException.FeatureFlagConfigurationNotFound` | Aucun feature flag n'a été trouvé pour le `featureKey` spécifié                                      |
| `KameleoonException.FeatureFlagVariationNotFound`     | Aucune variation de fonctionnalité n'a été trouvée pour les `visitorCode` et `variableKey` spécifiés |
| `KameleoonException.FeatureFlagEnvironmentDisabled`   | Le feature flag est désactivé pour l'environnement actuel                                            |
| `KameleoonException.JSONParse`                        | Impossible d'analyser la valeur JSON                                                                 |
| `KameleoonException.NumberParse`                      | Impossible d'analyser la valeur Number                                                               |

***

#### onConfigurationUpdate()

<Note>
  Utilisez plutôt la méthode `onEvent` avec `EventType.ConfigurationUpdate`.
</Note>

La méthode `onConfigurationUpdate` collectée avec le hook `useInitialize` déclenche un callback lors d'une mise à jour de la configuration du client.

<Note>
  Ce hook ne fonctionne que pour les server sent events de mise à jour en temps réel
</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

| Nom                   | Type         | Description                                                                                   |
| --------------------- | ------------ | --------------------------------------------------------------------------------------------- |
| callback (*required*) | `() => void` | fonction callback sans paramètres qui sera appelée lors de la mise à jour de la configuration |

##### Exceptions thrown

| Type                                | Description                                                                                   |
| ----------------------------------- | --------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization` | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |

***

#### getFeatureFlags()

🚫 *N'envoie pas de données de suivi à Kameleoon*

La méthode `getFeatureFlags` collectée avec le hook `useFeatureFlag` renvoie une liste de feature flags stockés dans la configuration client.

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

##### Return value

| Type                | Description                                                                    |
| ------------------- | ------------------------------------------------------------------------------ |
| `FeatureFlagType[]` | liste de feature flags, chaque élément de feature flag contient `id` et `key`. |

##### Exceptions thrown

| Type                                | Description                                                                                   |
| ----------------------------------- | --------------------------------------------------------------------------------------------- |
| `KameleoonException.Initialization` | La méthode a été exécutée avant que le `kameleoonClient` n'ait terminé son appel `initialize` |
