Skip to main content
The experiments module assigns users to variants using a deterministic hash. No server call is needed — assignment is instant, works offline, and the same user always gets the same variant.

Get Variant

final variant = AppDNA.experiments.getVariant("paywall-test");

if (variant == "variant_a") {
  showNewPaywall();
} else {
  showStandardPaywall(); // Always handle the default case
}
Returns the variant string or null if the experiment is not found, not running, or the user is not in the target audience.
Always handle the null / default case. Experiments can be archived or stopped at any time from the Console.

Module Access

final experiments = AppDNA.experiments;

Module Methods

MethodSignatureDescription
getVariantString? getVariant(String experimentId, {bool trackExposure = true})Get the assigned variant
trackExposurevoid trackExposure(String experimentId)Manually track an exposure event
set delegateset delegate(ExperimentDelegate?)Set a delegate for assignment callbacks

Exposure Tracking

Automatic (Default)

The SDK tracks an experiment_exposure event once per session the first time getVariant() is called for a given experiment.

Manual

Disable automatic tracking and track when the UI is actually visible:
final variant = AppDNA.experiments.getVariant("paywall-test", trackExposure: false);

// Later, when the paywall is actually displayed
void onPaywallVisible() {
  AppDNA.experiments.trackExposure("paywall-test");
}

ExperimentDelegate

class MyExperimentHandler extends ExperimentDelegate {
  @override
  void onAssignmentChanged(String experimentId, String? newVariant) {
    print("Experiment $experimentId now: ${newVariant ?? 'none'}");
  }
}

AppDNA.experiments.delegate = MyExperimentHandler();
Assignment changes are rare. They occur only when the experiment definition changes on the server, not on every session start.

Experiment Lifecycle

StatusgetVariant() returns
Draftnull — not visible to SDKs
RunningAssigned variant string
CompletedWinning variant for all users
Archivednull — removed from config

Full Example

import 'package:appdna_sdk/appdna_sdk.dart';

class PaywallExperiment extends ExperimentDelegate {
  PaywallExperiment() {
    AppDNA.experiments.delegate = this;
  }

  void showPaywall() {
    final variant = AppDNA.experiments.getVariant("paywall_redesign");

    final paywallId = variant == "new_design" ? "paywall_v2" : "paywall_v1";

    AppDNA.paywall.present(
      paywallId,
      context: PaywallContext(
        placement: "settings",
        experiment: "paywall_redesign",
        variant: variant ?? "control",
      ),
    );
  }

  @override
  void onAssignmentChanged(String experimentId, String? newVariant) {
    // Assignment changed mid-session (rare)
  }
}
Experiments are created in the Console under Experiments. The SDK uses MurmurHash3 for deterministic assignment — the same user always gets the same variant across sessions, platforms, and offline.