# Experiment React Native SDK (Legacy)

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

> **Warning:**
>
> The legacy SDK receives only bug fixes until deprecation. We recommend upgrading to `v1.0.0+`, which supports SDK integrations, React Native Web, Expo, and more.

Official documentation for Amplitude Experiment's Client-side React Native SDK.

## Install

> **Warning:** Web compatibility
>
> Experiment React Native SDK is only compatible with iOS and Android React Native projects. Use the [JavaScript SDK](https://amplitude.com/docs/sdks/experiment-sdks/experiment-javascript) to support all three platforms.

Install the Experiment JavaScript Client SDK.

#### npm

```bash
npm install --save @amplitude/experiment-react-native-client
```

#### yarn

```bash
yarn add @amplitude/experiment-react-native-client
```

> **Tip:** Quick start
>
> 1. [Initialize the experiment client](#initialize)
> 2. [Fetch variants for the user](#fetch)
> 3. [Access a flag's variant](#variant)
>
> ```js
> // (1) Initialize the experiment client
> await Experiment.initialize('<DEPLOYMENT_KEY>');
>
> // (2) Fetch variants for a user
> const user = {
>     user_id: 'user@company.com',
>     device_id: 'abcdefg',
>     user_properties: {
>         'premium': true,
>     },
> };
> await Experiment.fetch(user);
>
> // (3) Lookup a flag's variant
> const variant = await Experiment.variant('<FLAG_KEY>');
> if (variant.value === 'on') {
>     // Flag is on
> } else {
>     // Flag is off
> }
> ```

## Core functions

The following functions make up the core of the Experiment client-side SDK.

> **Info:** Async functions
>
> Native SDKs run internally, so you need to `await` the result of all functions.

### Initialize

Initialize the SDK client in your application on startup. The [deployment key](https://amplitude.com/docs/feature-experiment/data-model#deployments) argument you pass to the `apiKey` parameter must live within the same project that you are sending analytics events to.

```js
initialize(apiKey: string, config?: ExperimentConfig): Promise<boolean>
```

| Parameter | Requirement | Description |
| --- | --- | --- |
| `apiKey` | required | The [deployment key](https://amplitude.com/docs/feature-experiment/data-model#deployments) that authorizes fetch requests and determines which flags to evaluate for the user. |
| `config` | optional | The client [configuration](#configuration) used to customize SDK client behavior. |

The initializer returns a singleton instance, so subsequent initializations for the same instance name always return the initial instance. To create multiple instances, use the `instanceName` [configuration](#configuration).

```js
const experiment = await Experiment.initialize('<DEPLOYMENT_KEY>');
```

#### Integrations

If you use either Amplitude or Segment Analytics SDKs to track events into Amplitude, you'll want to set up an integration on initialization. Integrations automatically implement [provider](#providers) interfaces to enable a more streamlined developer experience by making it easier to **manage user identity** and **track exposures events**.

> **Info:** Amplitude integration
>
> The Amplitude Experiment SDK is set up to integrate with the Amplitude Analytics SDK. Update your SDK versions to the latest, and use the special integration initialization function.
>
> ```js
> await Amplitude.getInstance().init('<API_KEY>');
> await Experiment.initializeWithAmplitudeAnalytics('<DEPLOYMENT_KEY>');
> ```
>
> If you are using a custom instance name for analytics, set the same value in the `instanceName` [configuration option](#configuration) in the experiment SDK.
>
> The integration initializer configures implementations of the [user provider](#user-provider) and [exposure tracking provider](#exposure-tracking-provider) interfaces to pull user data from the Amplitude Analytics SDK and track exposure events.
>
> **Supported Versions**
>
> | Analytics SDK Version | Experiment SDK Version |
> | --- | --- |
> | `2.8.0+` | `0.6.0+` |

#### Configuration

Configure the SDK client during initialization.

| Name | Description | Default Value |
| --- | --- | --- |
| `debug` | Enable additional debug logging within the SDK. Should be set to false in production builds. | `false` |
| `fallbackVariant` | The default variant to fall back if a variant for the provided key doesn't exist. | `{}` |
| `initialVariants` | An initial set of variants to access. This field helps bootstrap the client SDK with values rendered by the server using server-side rendering (SSR). | `{}` |
| `serverUrl` | The host to fetch variants from. | `https://api.lab.amplitude.com` |
| `fetchTimeoutMillis` | The timeout for fetching variants in milliseconds. | `10000` |
| `retryFetchOnFailure` | Whether to retry variant fetches in the background if the request doesn't succeed. | `true` |
| `automaticExposureTracking` | If true, calling [`variant()`](#variant) tracks an exposure event through the configured `exposureTrackingProvider`. If no exposure tracking provider is set, this configuration option does nothing. | `true` |
| `automaticFetchOnAmplitudeIdentityChange` | Only matters if you use the `initializeWithAmplitudeAnalytics` initialization function to integrate with the Amplitude Analytics SDK. If `true` any change to the user ID, device ID or user properties from analytics triggers the experiment SDK to fetch variants and update its cache. | `false` |
| `userProvider` | An interface used to provide the user object to `fetch()` when called. | `null` |
| `exposureTrackingProvider` | Implement and configure this interface to track exposure events through the experiment SDK, either automatically or explicitly. | `null` |
| `instanceName` | Custom instance name for experiment SDK instance. **The value of this field is case-sensitive.** | `null` |

> **Info:** EU data center
>
> If you're using Amplitude's EU data center, configure the `serverUrl` option on initialization to `https://api.lab.eu.amplitude.com`

### Fetch

Fetches variants for a [user](https://amplitude.com/docs/feature-experiment/data-model#users) and stores the results in the client for fast access. The function [remote evaluates](https://amplitude.com/docs/feature-experiment/remote-evaluation) the user for flags associated with the deployment used to initialize the SDK client.

```js
fetch(user?: ExperimentUser): Promise<boolean>
```

| Parameter | Requirement | Description |
| --- | --- | --- |
| `user` | optional | Explicit [user](https://amplitude.com/docs/feature-experiment/data-model#users) information to pass with the request to evaluate. The SDK merges this user information with user information provided from [integrations](#integrations) through the [user provider](#user-provider), preferring properties passed explicitly to `fetch()` over provided properties. |

Amplitude recommends calling `fetch()` during application start up so that the user gets the most up-to-date variants for the application session. Furthermore, you'll need to wait for the fetch request to return a result before rendering the user experience to avoid the interface "flickering".

```js
const user = {
    user_id: 'user@company.com',
    device_id: 'abcdefg',
    user_properties: {
        'premium': true,
    },
};
await Experiment.fetch(user);
```

If you're using an [integration](#integrations) or a custom [user provider](#user-provider) then you can fetch without inputting the user.

```js
await Experiment.fetch();
```

> **Tip:** Fetch when user identity changes
>
> If you want the most up-to-date variants for the user, call `fetch()` whenever the user state changes in a meaningful way. For example, if the user logs in and receives a user ID, or has a user property set which may affect flag or experiment targeting rules.
>
> In the case of **user properties**, Amplitude recommends passing new user properties explicitly to `fetch()` instead of relying on user enrichment before [remote evaluation](https://amplitude.com/docs/feature-experiment/remote-evaluation). Remote user-property sync through a separate system has no timing guarantees for `fetch()`, which can create a race condition.

> **Tip:** Timeout and retries
>
> If `fetch()` times out (default 10 seconds) or fails for any reason, the SDK client returns and retries in the background with back-off. You may configure the timeout or disable retries in the [configuration options](#configuration) during SDK client initialization.

### Variant

Access a [variant](https://amplitude.com/docs/feature-experiment/data-model#variants) for a [flag or experiment](https://amplitude.com/docs/feature-experiment/data-model#flags-and-experiments) from the SDK client's local store.

> **Info:** Automatic exposure tracking
>
> When you use an [integration](#integrations) or set a custom [exposure tracking provider](#exposure-tracking-provider), `variant()` automatically tracks an exposure event through the tracking provider. To disable this functionality, [configure](#configuration) `automaticExposureTracking` to be `false`, and track exposures manually using [`exposure()`](#exposure).

```js
variant(key: string): Promise<Variant>
```

```js
variantWithFallback(key: string, fallback: Variant): Promise<Variant>
```

| Parameter | Requirement | Description |
| --- | --- | --- |
| `key` | required | The **flag key** to identify the [flag or experiment](https://amplitude.com/docs/feature-experiment/data-model#flags-and-experiments) to access the variant for. |
| `fallback` | optional | The value to return if no variant was found for the given `flagKey`. |

When determining which variant a user has been bucketed into, you'll want to compare the variant `value` to a well-known string.

```js
const variant = await Experiment.variant('<FLAG_KEY>');
if (variant.value === 'on') {
    // Flag is on
} else {
    // Flag is off
}
```

> **Info:** Access the variant's payload
>
> A variant may also be configured with a dynamic [payload](https://amplitude.com/docs/feature-experiment/data-model#variants) of arbitrary data. Access the `payload` field from the variant object after checking the variant's `value`.
>
> ```js
> const variant = await Experiment.variant('<FLAG_KEY>');
> if (variant.value === 'on') {
>     const payload = variant.payload;
> }
> ```

A `null` variant `value` means that the user hasn't been bucketed into a variant. You may use the built in **fallback** parameter to provide a variant to return if the store doesn't contain a variant for the given flag key.

```js
const variant = await Experiment.variantWithFallback('<FLAG_KEY>', { value: 'control' });
if (variant === 'control') {
    // Control
} else if (variant === 'treatment') {
    // Treatment
}
```

### All

Access all [variants](https://amplitude.com/docs/feature-experiment/data-model#variants) stored by the SDK client.

```js
all(): Promise<Variants>
```

### Exposure

Manually track an [exposure event](https://amplitude.com/docs/feature-experiment/under-the-hood/event-tracking#exposure-events) for the current variant of the given flag key through configured [integration](#integrations) or custom [exposure tracking provider](#exposure-tracking-provider). Generally used in conjunction with setting the `automaticExposureTracking` [configuration](#configuration) optional to `false`.

```js
exposure(key: string): Promise<boolean>
```

| Parameter | Requirement | Description |
| --- | --- | --- |
| `key` | required | The **flag key** to identify the [flag or experiment](https://amplitude.com/docs/feature-experiment/data-model#flags-and-experiments) variant to track an [exposure event](https://amplitude.com/docs/feature-experiment/under-the-hood/event-tracking#exposure-events) for. |

```js
const variant = await Experiment.variant('<FLAG_KEY>');

// Do other things...

await Experiment.exposure('<FLAG_KEY>');
if (variant === 'control') {
    // Control
} else if (variant === 'treatment') {
    // Treatment
}
```
