> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly-preview.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Flag evaluation reasons: Client-side SDKs

> This topic explains how to use the flag evaluation reason feature to get more information about the flag variations LaunchDarkly serves to contexts or users. This page covers client-side sdks.

> For the complete documentation index, see [llms.txt](/llms.txt). For the full documentation snapshot, see [llms-full.txt](/llms-full.txt).

## Client-side SDKs

<Warning title="An evaluation reason configuration option is required">
  In client-side SDKs, you must enable an evaluation reason configuration option for this feature to work. The code samples below include this option. To learn more about configuration options, read [Configuration](/sdk/features/config).
</Warning>

This feature is available in the following client-side SDKs:

* [.NET (client-side)](#net-client-side)
* [Android](#android)
* [C++ (client-side)](#c-client-side)
* [Electron](#electron)
* [Flutter](#flutter)
* [iOS](#ios)
* [JavaScript](#javascript)
* [Node.js (client-side)](#nodejs-client-side)
* [React Native](#react-native)
* [Roku](#roku)

### .NET (client-side)

<Accordion title="Expand .NET (client-side) code sample">
  The `VariationDetail` methods, such as `BoolVariationDetail`, work the same as `Variation`, but also provide additional "reason" information about how a flag value was calculated. For example, you can find out if the context was individually targeted for the flag or was matched by one of the flag's rules. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export.

  Here is an example:

  <CodeGroup>
    ```csharp title=".NET SDK v4.0 (C#)" theme={null}

          var config = Configuration
              .Builder("example-mobile-key", ConfigurationBuilder.AutoEnvAttributes.Enabled)
              .EvaluationReasons(true)
              .Build();
          LdClient client = LdClient.Init(config, context);

          EvaluationDetail<bool> detail =
              client.BoolVariationDetail("example-bool-flag-key", false);
              // or StringVariationDetail for a string-valued flag, and so on.

          bool value = detail.Value;
          int? index = detail.VariationIndex;
          EvaluationReason reason = detail.Reason;
    ```

    ```csharp title=".NET SDK v3.0 (C#)" theme={null}

          var config = Configuration
              .Builder("example-mobile-key")
              .EvaluationReasons(true)
              .Build();
          LdClient client = LdClient.Init(config, context);

          EvaluationDetail<bool> detail =
              client.BoolVariationDetail("example-bool-flag-key", false);
              // or StringVariationDetail for a string-valued flag, and so on.

          bool value = detail.Value;
          int? index = detail.VariationIndex;
          EvaluationReason reason = detail.Reason;
    ```
  </CodeGroup>

  To learn more about the `VariationDetail` methods, read [`EvaluationDetail`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/client/api/LaunchDarkly.Sdk.EvaluationDetail-1.html) and [`BoolVariationDetail`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/client/api/LaunchDarkly.Sdk.Client.LdClient.html#LaunchDarkly_Sdk_Client_LdClient_BoolVariationDetail_). To learn more about the configuration option, read [`EvaluationReasons`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/client/api/LaunchDarkly.Sdk.Client.ConfigurationBuilder.html#LaunchDarkly_Sdk_Client_ConfigurationBuilder_EvaluationReasons_System_Boolean_).
</Accordion>

### Android

<Accordion title="Expand Android code sample">
  The `variationDetail` methods, such as `boolVariationDetail`, work the same as `variation`. They also provide additional "reason" information about how a flag value was calculated, such as if the context matched a specific rule. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export.

  Here is an example:

  <CodeGroup>
    ```java title="Android SDK v5.x (Java)" theme={null}
          LDConfig ldConfig = new LDConfig.Builder(AutoEnvAttributes.Enabled)
            .mobileKey("example-mobile-key")
            .evaluationReasons(true)
            .build();
          LDClient client = LDClient.init(this.getApplication(), ldConfig, context, secondsToBlock);

          EvaluationDetail<Boolean> detail =
            client.boolVariationDetail("example-flag-key", false);
            // or stringVariationDetail for a string-valued flag, etc.

          boolean value = detail.getValue();
          Integer index = detail.getVariationIndex();
          EvaluationReason reason = detail.getReason();
    ```

    ```java title="Android SDK v4.x (Java)" theme={null}
          LDConfig ldConfig = new LDConfig.Builder()
            .mobileKey("example-mobile-key")
            .evaluationReasons(true)
            .build();
          LDClient client = LDClient.init(this.getApplication(), ldConfig, context, secondsToBlock);

          EvaluationDetail<Boolean> detail =
            client.boolVariationDetail("example-flag-key", false);
            // or stringVariationDetail for a string-valued flag, etc.

          boolean value = detail.getValue();
          Integer index = detail.getVariationIndex();
          EvaluationReason reason = detail.getReason();
    ```
  </CodeGroup>

  To learn more about the `variationDetail` methods, read [`EvaluationDetail`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/EvaluationDetail.html) and [`getVariationIndex`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/EvaluationDetail.html#getVariationIndex--). To learn more about the configuration option, read [`evaluationReasons`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/android/LDConfig.Builder.html#evaluationReasons\(boolean\)).

  Here is an example of how to access the details of a reason object:

  <CodeGroup>
    ```java title="Java" theme={null}
          void printReason(EvaluationReason reason) {
            switch (reason.getKind()) {
              case OFF:
                Timber.d("it's off");
                break;
              case FALLTHROUGH:
                Timber.d("fell through");
                break;
              case TARGET_MATCH:
                Timber.d("targeted");
                break;
              case RULE_MATCH:
                EvaluationReason.RuleMatch rm =
                  (EvaluationReason.RuleMatch)reason;
                Timber.d("matched rule %d/%s",
                         rm.getRuleIndex(),
                         rm.getRuleId());
                break;
              case PREREQUISITE_FAILED:
                EvaluationReason.PrerequisiteFailed pf =
                  (EvaluationReason.PrerequisiteFailed)reason;
                Timber.d("prereq failed: %s", pf.getPrerequisiteKey());
                break;
              case ERROR:
                EvaluationReason.Error e = (EvaluationReason.Error)reason;
                Timber.d("error: %s", e.getErrorKind());
            }
            // or, if all you want is a simple descriptive string:
            Timber.d(reason.toString());
          }
    ```
  </CodeGroup>

  To learn more, read [`EvaluationReason`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/EvaluationReason.html).
</Accordion>

### C++ (client-side)

<Accordion title="Expand C++ (client-side) code sample">
  You can request and then programmatically inspect the reason for a particular feature flag evaluation.

  The `detail.Reason()` response is described in [Evaluation reasons](/sdk/concepts/evaluation-reasons).

  Here is an example:

  <CodeGroup>
    ```cpp title="C++ SDK v3.0 (native)" theme={null}
          auto detail = client.BoolVariationDetail("example-flag-key", false);
          if (detail.Value()) {
            std::cout << "Value was true!" << std::endl;
          } else {
            // it was false, let's find out why.
            if (auto reason = detail.Reason(); reason.has_value()) {
              // reason might not be present, so we have to check
              std::cout << "Value was false because of " << reason.value() << std::endl;
            } else {
              std::cout << "No reason provided to explain why flag was false!" << std::endl;
            }
          }
    ```

    ```c title="C++ SDK v3.0 (C binding)" theme={null}
          LDEvalDetail detail;
          if (LDClientSDK_BoolVariationDetail(client, "example-flag-key", false, &detail)) {
              printf("Value was true!\n");
          } else {
              LDEvalReason reason;
              if (LDEvalDetail_Reason(detail, &reason)) {
                 printf("Value was false because of %d\n", LDEvalReason_Kind(reason));
              } else {
                 printf("No reason provided to explain why flag was false!\n");
              }
          }
    ```

    ```c title="C SDK v2.x (native)" theme={null}
          struct LDConfig *config = LDConfigNew("example-mobile-key");
          LDConfigSetUseEvaluationReasons(config, LDBooleanTrue);
          struct LDClient *client = LDClientInit(config, user, maxwaitmilliseconds);

          LDVariationDetails details;
          LDBoolean value;

          value = LDBoolVariationDetail(client, "your.feature.key", LDBooleanFalse, &details);

          /* inspect details.reason, which is a JSON object */
          if (strcmp(LDGetText(LDObjectLookup(details->reason, "errorKind")), "FLAG_NOT_FOUND") == 0) {
              /* ... */
          }

          LDFreeDetailContents(&details);
    ```

    ```cpp title="C SDK v2.x (C++ binding)" theme={null}
          struct LDConfig *config = LDConfigNew("example-mobile-key");
          LDConfigSetUseEvaluationReasons(config, LDBooleanTrue);
          LDClientCPP *client = LDClientCPP::Init(config, user, maxwaitmilliseconds);

          LDVariationDetails details;

          bool value = client->boolVariationDetail("your.feature.key", false, &details);

          /* inspect details.reason, which is a JSON object */
          if (strcmp(LDGetText(LDObjectLookup(details->reason, "errorKind")), "FLAG_NOT_FOUND") == 0) {
          /* ... */
          }

          LDFreeDetailContents(&details);
    ```
  </CodeGroup>

  To learn more, read [`EvaluationDetail`](https://launchdarkly.github.io/cpp-sdks/libs/client-sdk/docs/html/classlaunchdarkly_1_1EvaluationDetail.html) and [`BoolVariationDetail`](https://launchdarkly.github.io/cpp-sdks/libs/client-sdk/docs/html/classlaunchdarkly_1_1client__side_1_1Client.html#a81d57edf13a87562d328174d7f9d6f09).
</Accordion>

### Electron

<Accordion title="Expand Electron code sample">
  The `variationDetail` methods work the same as `variation`. They also provide additional "reason" information about how a flag value was calculated. For example, you can find out if the context was individually targeted for the flag or was matched by one of the flag's rules. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export.

  Here is an example:

  <CodeGroup>
    ```js title="JavaScript" theme={null}

          const { value, variationIndex, reason } = client.variationDetail('example-flag-key', false);
    ```

    ```ts title="TypeScript" theme={null}
          const { value, variationIndex, reason } = client.variationDetail('example-flag-key', false);
    ```
  </CodeGroup>

  To learn more about the `variationDetail` methods, read [`LDEvaluationDetail`](https://launchdarkly.github.io/electron-client-sdk/interfaces/_launchdarkly_electron_client_sdk_.ldevaluationdetail.html) and [`variationDetail`](https://launchdarkly.github.io/electron-client-sdk/interfaces/_launchdarkly_electron_client_sdk_.ldelectronmainclient.html#variationdetail). To learn more about the configuration option, read [`LDEvaluationReason`](https://launchdarkly.github.io/electron-client-sdk/index.html#ldevaluationreason).
</Accordion>

### Flutter

<Accordion title="Expand Flutter code sample">
  The `variationDetail` methods, such as `boolVariationDetail`, work the same as `variation`. They also provide additional "reason" information about how a flag value was calculated. For example, you can find out if the context was individually targeted for the flag or was matched by one of the flag's rules. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export.

  To enable this functionality, set the `evaluationReasons` configuration option to `true` when you initialize the client.

  Here is an example:

  <CodeGroup>
    ```dart title="Flutter SDK v4" theme={null}
          final config = LDConfig(
            CredentialSource.fromEnvironment(),
            AutoEnvAttributes.enabled,
            dataSourceConfig: DataSourceConfig(
              evaluationReasons: true
            ),
          );

          // initialize client and context

          LDEvaluationDetail<bool> detail =
            client.boolVariationDetail('example-flag-key', false);
            // or stringVariationDetail for a string-valued flag, and so on.

          bool value = detail.value;
          int index = detail.variationIndex;
          LDEvaluationReason reason = detail.reason;
    ```

    ```dart title="Flutter SDK v3.x" theme={null}
          LDConfig config = LDConfigBuilder('example-mobile-key', AutoEnvAttributes.Enabled)
              .evaluationReasons(true)
              .build();

          // initialize client and context

          LDEvaluationDetail<bool> detail =
            await LDClient.boolVariationDetail('example-flag-key', false);
            // or stringVariationDetail for a string-valued flag, and so on.

          bool value = detail.value;
          int index = detail.variationIndex;
          LDEvaluationReason reason = detail.reason;
    ```
  </CodeGroup>

  To learn more about the `variationDetail` methods, read [`LDEvaluationDetail`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/LDEvaluationDetail-class.html) and [`boolVariationDetail`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/LDClient/boolVariationDetail.html). To learn more about the configuration option, read [`evaluationReasons`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/DataSourceConfig/evaluationReasons.html).

  Here is an example of how to access the details of a reason object:

  <CodeGroup>
    ```dart title="Dart" theme={null}
          void printReason(LDEvaluationReason reason) {
            switch (reason.kind) {
              case LDKind.OFF:
                print("it's off");
                break;
              case LDKind.FALLTHROUGH:
                print('fell through');
                break;
              case LDKind.TARGET_MATCH:
                print('targeted');
                break;
              case LDKind.RULE_MATCH:
                print('matched rule: ${reason.ruleIndex} ${reason.ruleId}');
                break;
              case LDKind.PREREQUISITE_FAILED:
                print('prereq failed: ${reason.prerequisiteKey}');
                break;
              case LDKind.ERROR:
                print('error: ${reason.errorKind}');
                break;
              default: // LDKind.UNKNOWN
                print('unknown service kind');
            }
          }
    ```
  </CodeGroup>

  To learn more, read [`LDEvaluationDetail`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/LDEvaluationDetail-class.html).
</Accordion>

### iOS

<Accordion title="Expand iOS code sample">
  The `variationDetail` methods, such as `boolVariationDetail`, work the same as the variation methods. They also provide additional "reason" information about how a flag value was calculated, such as if the user matched a specific rule. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export.

  Here is an example:

  <CodeGroup>
    ```swift title="iOS SDK v8.0+ (Swift)" theme={null}
          ldConfig.evaluationReasons = true
          LDClient.start(config: ldConfig, context: context)

          let detail = client.boolVariationDetail(forKey: "example-flag-key", defaultValue: false);

          let value: Bool = detail.value
          let variationIndex: Int? = detail.variationIndex
          let reason: [String: LDValue]? = detail.reason
    ```

    ```objc title="iOS SDK v8.0+ (Objective-C)" theme={null}
          config.evaluationReasons = true;
          [LDClient startWithConfiguration:config context:result.success completion: nil];

          LDBoolEvaluationDetail *detail = [[LDClient get] boolVariationDetailForKey:@"example-flag-key" defaultValue:NO];

          BOOL value = detail.value;
          NSInteger variationIndex = detail.variationIndex;
          NSDictionary<NSString*, LDValue*> *reason = detail.reason;
    ```
  </CodeGroup>

  To learn more about the `variationDetail` methods, read [`LDEvaluationDetail`](https://launchdarkly.github.io/ios-client-sdk/Classes/LDEvaluationDetail.html) and [`boolVariationDetail`](https://launchdarkly.github.io/ios-client-sdk/Classes/LDClient.html#/s:12LaunchDarkly8LDClientC19boolVariationDetail6forKey12defaultValueAA012LDEvaluationF0CySbGSS_SbtF). To learn more about the configuration option, read [`LDConfig`](https://launchdarkly.github.io/ios-client-sdk/Structs/LDConfig.html).
</Accordion>

### Java

Script

<Accordion title="Expand JavaScript code sample">
  The `variationDetail` method lets you evaluate a feature flag with the same parameters you would for `variation`. With `variationDetail`, you receive more information about how the value was calculated. In v4.x of the JavaScript SDK you can also use typed methods, for example, `boolVariationDetail` for boolean feature flags.

  The variation detail returns in an object containing both the result value and a "reason" object which tells you more information about the flag evaluation. For example, you can find out if the context was individually targeted for the flag or was matched by one of the flag's rules. It also indicates if the flag returned the default value due to an error. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export.

  Here is an example:

  <CodeGroup>
    ```ts title="JavaScript SDK v4.x" theme={null}
          const options = { evaluationReasons: true };
          // Create client
          const client = createClient('example-client-side-id', context, options);

          // Then start the client
          client.start();

          client.waitForInitialization({timeout: 5});

            if (result.status === 'complete') {
            // Client initialized successfully
            } else if (result.status === 'failed') {
            // Client failed to initialize
            console.error('Initialization failed:', result.error);
            } else if (result.status === 'timeout') {
            // Initialization timed out
            console.error('Initialization timed out');
            }

            // Note: Events still work if you prefer that approach
            client.on('ready', () => {
            // Client is ready (success or failure)
            });
            client.on('initialized', () => {
            // Client initialized successfully
            });
            client.on('failed', (err) => {
            // Client failed to initialize
            });
    ```

    ```js title="JavaScript SDK v3.x" theme={null}
          const options = { evaluationReasons: true };
          const client = LDClient.initialize('example-client-side-id', context, options);

          try {
              client.waitForInitialization(5);

              // proceed with successfully initialized client:

              const detail = client.variationDetail('example-flag-key', false);

              const value = detail.value;
              const index = detail.variationIndex;
              const reason = detail.reason;

          } catch(err) {
              // Client failed to initialize or timed out
              // variation() calls return fallback values until initialization completes
          }
    ```
  </CodeGroup>

  To learn more about the `*variationDetail` methods, read [`LDEvaluationDetail`](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/types/LDEvaluationDetail.html). To learn more about the configuration option, read [`evaluationReasons`](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/interfaces/LDOptions.html#evaluationReasons).
</Accordion>

### Node.js (client-side)

<Accordion title="Expand Node.js (client-side) code sample">
  The `variationDetail` method lets you evaluate a feature flag with the same parameters you would for `variation`. With `variationDetail`, you receive more information about how the value was calculated.

  The variation detail returns in an object that contains both the result value and a "reason" object which tells you more information about the flag evaluation. For example, you can find out if the user was individually targeted for the flag or was matched by one of the flag's rules. It also indicates if the flag returned the default value due to an error. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export.

  Here is an example:

  <CodeGroup>
    ```js title="JavaScript" theme={null}
          const options = { evaluationReasons: true };
          const client = LDClient.initialize('example-client-side-id', user, options);

          const detail = client.variationDetail('example-flag-key', false);

          const value = detail.value;
          const index = detail.variationIndex;
          const reason = detail.reason;
    ```
  </CodeGroup>

  To learn more about the `variationDetail` method, read [`LDEvaluationDetail`](https://launchdarkly.github.io/node-client-sdk/interfaces/LDEvaluationDetail.html) and [`variationDetail`](https://launchdarkly.github.io/node-client-sdk/interfaces/LDClient.html#variationDetail). To learn more about the configuration option, read [`evaluationReasons`](https://launchdarkly.github.io/node-client-sdk/interfaces/LDOptions.html#evaluationReasons).
</Accordion>

### React Native

<Accordion title="Expand React Native code sample">
  The `variationDetail` methods work the same way as the [`variation` methods](/sdk/features/evaluating#react-native), and also provide additional information about how a flag value was calculated. For example, you can find out if the context was individually targeted for the flag or was matched by one of the flag's rules. You can examine the "reason" data programmatically, or, if you capture detailed analytics events for flags, view it with Data Export. To view this reason information, set the `withReasons` configuration option to `true`.

  In React Native, there is a variation detail method for each type, such as `boolVariationDetail` or `stringVariationDetail`. In the React Native SDK version 10, there is also a hook for each type, such as `useBoolVariationDetail` or `useStringVariationDetail`.

  Here is an example:

  <CodeGroup>
    ```js title="React Native SDK v10, using variation hooks" theme={null}
          const { reason, value, variationIndex } = useBoolVariationDetail('example-flag-key', false);
    ```

    ```js title="React Native SDK v10, using variation methods" theme={null}
          const { reason, value, variationIndex } = client.boolVariationDetail('example-flag-key', false);
    ```
  </CodeGroup>

  To learn more about the `variationDetail` methods, read [`LDEvaluationDetail`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/interfaces/platform-1.LDEvaluationDetail.html), [`useBoolVariationDetail`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/functions/useBoolVariationDetail.html) and [`boolVariationDetail`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/classes/LDClientImpl.html#boolVariationDetail).

  To learn more about the `withReasons` configuration option, read [`LDOptions`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/interfaces/LDOptions.html#withReasons).

  The SDK also includes an untyped method to determine the variation of a feature flag and provide information about how the flag value was calculated. To learn more, read [`variationDetail`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/classes/LDClientImpl.html#variationDetail). We recommend using the strongly typed variation methods, such as `boolVariationDetail`, which perform type checks and handle type errors.
</Accordion>

### Roku

<Accordion title="Expand Roku code sample">
  For each variation type there is also an associated version that returns the reason a particular value was returned.

  Here is an example:

  <CodeGroup>
    ```brightscript title="BrightScript" theme={null}
          config.setUseEvaluationReasons(true)

          details = launchDarkly.intVariationDetail("example-flag-key", 123)

    ```
  </CodeGroup>

  These variation methods return an object containing the keys `value`, `reason`, and `variationIndex`. The `value` field is the result of the evaluation. The `reason` field is an object that explains why the result happened, for example details about a rule match. The reason object will always contain a `kind` field. Lastly the `variationIndex` field contains the ID of the particular value returned. This field may be null.
</Accordion>
