Experimentation

This topic explains how to set up select client-side LaunchDarkly SDKs to use the Experimentation feature.

The configuration requirements for individual SDKs are included below.

Client-side SDKs

Code samples for this feature are available for the following client-side SDKs:

Android

To use Experimentation with the Android SDK, you must configure the following SDK features:

  • Track: Track methods send custom events to LaunchDarkly using an event key when a user or other context takes an action in your app. You use the event key with LaunchDarkly metrics to measure signals during an experiment.

    This example shows how to initialize the SDK with the track call included:

    Android SDK initialization for Experimentation
    1import com.launchdarkly.sdk.*
    2import com.launchdarkly.sdk.android.*
    3import com.launchdarkly.sdk.android.LDConfig.Builder.AutoEnvAttributes
    4
    5// This is your mobile key.
    6val ldConfig = LDConfig.Builder(AutoEnvAttributes.Enabled)
    7 .mobileKey("YOUR_MOBILE_KEY")
    8 .build()
    9
    10// A "context" is a data object representing users, devices, organizations, and other entities.
    11val context = LDContext.create("EXAMPLE_CONTEXT_KEY")
    12
    13// If you don't want to block execution while the SDK tries to get
    14// latest flags, move this code into an async IO task and await on its completion.
    15val client: LDClient = LDClient.init(this@BaseApplication, ldConfig, context, 5)
    16
    17// Call trackMetric when a metric action occurs in your app —
    18// a tap, a form submit, a screen view, a custom event, whatever your metric measures.
    19fun trackMetric(metricKey: String, data: LDValue = LDValue.ofNull()) {
    20 LDClient.get().trackData(metricKey, data)
    21}
  • Variation: Variation methods evaluate a flag for a specific context and return the variation value. Variation methods also record an exposure event so LaunchDarkly knows this context was part of the experiment. Use typed variation methods such as stringVariation() or boolVariation() that match your flag’s value type. Call a variation method after identify() has completed, and call it where the experience is rendered rather than in onCreate() or application startup.

  • Identify: Identify methods update the context the SDK uses for flag evaluation. All flags re-evaluate against the new context when it completes. You need identify() when a user or other context logs in, switches accounts, or their attributes change mid-session in a way that affects targeting, for example, an in-app purchase or plan upgrade. Always call identify() off of the main thread. It is a network operation and will block the UI if called on the main thread. Wrap it in a coroutine: CoroutineScope(Dispatchers.IO).launch { client.identify(ctx).get() }.

  • Flush: Flush methods force the SDK to send all queued events, including exposures and conversions, to LaunchDarkly immediately instead of waiting for the automatic send interval.

iOS

To use Experimentation with the iOS SDK, you must configure the following SDK features:

  • Track: Track methods send custom events to LaunchDarkly using an event key when a user or other context takes an action in your app.

    This example shows how to initialize the SDK with the track call included:

    iOS SDK initialization for Experimentation
    1import LaunchDarkly
    2
    3// Call this once from your app startup (e.g. application(_:didFinishLaunchingWithOptions:)).
    4// You can't invoke LDClient.start() at the top level in Swift — wrap it in a function.
    5func startLaunchDarkly() {
    6 // This is your mobile key.
    7 let config = LDConfig(mobileKey: "YOUR_MOBILE_KEY", autoEnvAttributes: .enabled)
    8
    9 // A "context" is a data object representing users, devices, organizations, and other entities.
    10 let contextBuilder = LDContextBuilder(key: "EXAMPLE_CONTEXT_KEY")
    11 guard case .success(let context) = contextBuilder.build() else { return }
    12
    13 LDClient.start(config: config, context: context, startWaitSeconds: 5) { timedOut in
    14 if timedOut {
    15 print("SDK didn't initialize in 5 seconds. SDK is still running and trying to get latest flags.")
    16 } else {
    17 print("SDK successfully initialized with the latest flags")
    18 }
    19 }
    20}
    21
    22// Call trackMetric when a metric action occurs in your app —
    23// a tap, a form submit, a screen view, a custom event, whatever your metric measures.
    24func trackMetric(metricKey: String, data: LDValue = .null) {
    25 let client = LDClient.get()!
    26 client.track(key: metricKey, data: data)
    27}
  • Variation: Variation methods evaluate a flag for a specific context and return the variation value. Variation methods also record an exposure event so LaunchDarkly knows this user or other context was part of the experiment.

  • Identify: Identify methods update the context the SDK uses for flag evaluation. All flags re-evaluate against the new context when it completes.

  • Flush: Flush methods force the SDK to send all queued events, including exposures and conversions, to LaunchDarkly immediately instead of waiting for the automatic send interval.

JavaScript

To use Experimentation with the JavaScript SDK, you must configure the following SDK features:

  • Track: Track methods send custom events to LaunchDarkly using an event key when a user or other context takes an action in your app.

    This example shows how to initialize the SDK with the track call included:

    JavaScript SDK initialization for Experimentation
    1import { createClient } from '@launchdarkly/js-client-sdk';
    2
    3// A "context" is a data object representing users, devices, organizations, and
    4// other entities. You'll need this later, but you can ignore it for now.
    5const context = {
    6 kind: 'user',
    7 key: 'EXAMPLE_CONTEXT_KEY',
    8};
    9
    10// This is your client-side ID.
    11const ldClient = createClient('YOUR_CLIENT_SIDE_ID', context);
    12
    13// await start — you only need waitForInitialization() if you wait somewhere
    14// other than where you start the client.
    15await ldClient.start();
    16console.log('SDK successfully initialized!');
    17
    18// Call trackMetric when a metric action occurs in your app —
    19// a click, a form submit, a page view, a custom event, whatever your metric measures.
    20function trackMetric(metricKey, data) {
    21 ldClient.track(metricKey, data);
    22}
  • Variation: Variation methods evaluate a flag for a specific context and return the variation value. Variation methods also record an exposure event so LaunchDarkly knows this user or other context was part of the experiment. Call ldClient.variation() at the exact moment the context encounters the experience, not at initialization, and not cached ahead of time.

  • Identify: Identify methods update the context the SDK uses for flag evaluation. All flags re-evaluate against the new context when it completes. You need identify() when the context’s identity changes after the SDK has already initialized, for example, when a user on a public page logs in, when identity loads asynchronously after SDK startup, or when a user completes a cookie consent flow. You do not need it if the user is already logged in when the page loads. Pass their context in the initial configuration instead.

  • Flush: Flush methods force the SDK to send all queued events, including exposures and conversions, to LaunchDarkly immediately instead of waiting for the automatic send interval. Call flush() after track() on any event that causes navigation, such as a button click that redirects, a form submission, or a link, because the page may unload before the automatic flush fires. Also call it on single-page application (SPA) route changes where the user leaves the current view.

React Native

To use Experimentation with the React Native SDK, you must configure the following SDK features:

  • Track: Track methods send custom events to LaunchDarkly using an event key when a user or other context takes an action in your app.

    This example shows how to initialize the SDK with the track call included:

    React Native SDK initialization for Experimentation
    1import React, { useEffect, useState, useCallback } from 'react';
    2import {
    3 AutoEnvAttributes,
    4 LDProvider,
    5 ReactNativeLDClient,
    6} from '@launchdarkly/react-native-client-sdk';
    7
    8// This is your mobile key.
    9const ldClient = new ReactNativeLDClient('YOUR_MOBILE_KEY', AutoEnvAttributes.Enabled, {
    10 debug: true,
    11 applicationInfo: {
    12 id: 'ld-rn-test-app',
    13 version: '0.0.1',
    14 },
    15});
    16
    17// A "context" is a data object representing users, devices, organizations, and other entities.
    18const context = { kind: 'user', key: 'EXAMPLE_CONTEXT_KEY' };
    19
    20export default function App() {
    21 const [ready, setReady] = useState<boolean>(false);
    22 // Wait for identify to complete before rendering, so no flag evaluates
    23 // against defaults during startup.
    24 useEffect(() => {
    25 (async () => {
    26 await ldClient.identify(context);
    27 setReady(true);
    28 })();
    29 }, []);
    30 // Call trackMetric when a metric action occurs in your app —
    31 // a tap, a form submit, a screen view, a custom event, whatever your metric measures.
    32 const trackMetric = useCallback(
    33 (metricKey: string, data?: unknown) => {
    34 ldClient.track(metricKey, data);
    35 },
    36 [],
    37 );
    38 if (!ready) return null;
    39 return (
    40 <LDProvider client={ldClient}>
    41 <YourComponent />
    42 </LDProvider>
    43 );
    44}
  • Variation: Variation methods evaluate a flag for a specific context and return the variation value. Variation methods also record an exposure event so LaunchDarkly knows this context was part of the experiment. Use the typed hooks such as useBoolVariation(), useStringVariation(), and useNumberVariation(). These hooks are reactive and return a typed value with a per-call-site default, so you get the right type and a fallback without having to check the result afterward.

  • Identify: Identify methods update the context the SDK uses for flag evaluation. All flags re-evaluate against the new context when it completes. You need identify() in the same scenarios as the JavaScript SDK, as well as when a user switches accounts on a shared device or completes onboarding and becomes a known entity mid-session. Always await the result before evaluating experiment flags, but await with a timeout. identify() is not guaranteed to complete on a slow or offline network, so waiting indefinitely can make your app unavailable during a network outage.

  • Flush: Flush methods force the SDK to send all queued events, including exposures and conversions, to LaunchDarkly immediately instead of waiting for the automatic send interval. Call flush() in an AppState change listener when state leaves active, so queued events are sent before the app moves to the background.

React Web

To use Experimentation with the React Web SDK, you must configure the track, variation, identify, and flush methods.

This example shows how to initialize the SDK with the track call included:

React Web SDK initialization for Experimentation
1// Add the code below to the root of your React app.
2import { StrictMode, useCallback } from 'react';
3import { createRoot } from 'react-dom/client';
4import { createLDReactProvider, useLDClient } from '@launchdarkly/react-sdk';
5
6function App() {
7 const ldClient = useLDClient();
8 // Call trackMetric when a metric action occurs in your app —
9 // a click, a form submit, a page view, a custom event, whatever your metric measures.
10 const trackMetric = useCallback(
11 (metricKey: string, data?: unknown) => {
12 ldClient?.track(metricKey, data);
13 },
14 [ldClient],
15 );
16 return <div>Let your feature flags fly!</div>;
17}
18
19// A "context" is a data object representing users, devices, organizations, and other entities.
20const context = {
21 kind: 'user',
22 key: 'EXAMPLE_CONTEXT_KEY',
23 email: 'biz@face.dev',
24};
25
26// Initialize the SDK so flag values are ready before your app renders.
27// This is your client-side ID.
28const LDProvider = createLDReactProvider('YOUR_CLIENT_SIDE_ID', context);
29
30createRoot(document.getElementById('root') as HTMLElement).render(
31 <StrictMode>
32 <LDProvider>
33 <App />
34 </LDProvider>
35 </StrictMode>,
36);

The React Web SDK relies on the JavaScript SDK for the variation, identify, and flush methods. The same guidance applies.