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

# Context configuration: Client-side SDKs

> This topic explains how to configure contexts in LaunchDarkly SDKs. This feature is available for both client-side and server-side SDKs. 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

Here are the configuration options for contexts in 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)
* [React Web](#javascript): The React Web SDK relies on the JavaScript SDK for context-related functionality.
* [Roku](#roku)

### .NET (client-side)

<Accordion title="Expand .NET (client-side) code sample">
  In the client-side .NET SDK, you can construct a `Context` that only has a key by calling `Context.New`. The context kind defaults to "user," or you can supply a different context kind. Alternatively, you can use `Context.Builder`, which allows setting all properties.

  The argument to `Builder` is the context's key. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example:

  <CodeGroup>
    ```csharp title=".NET SDK v3.0+ (C#)" theme={null}
          Context context = Context.Builder("example-context-key")
              .Set("firstName", "Sandy")
              .Set("lastName", "Smith")
              .Set("email", "sandy@example.com")
              .Set("group", "microsoft")
              .Build();
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```csharp title=".NET SDK v3.0+ (C#)" theme={null}
          var context = Context.New(ContextKind.Of("organization"), "example-organization-key");
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```csharp title=".NET SDK v3.0+ (C#)" theme={null}
          var userContext = Context.New("example-user-key");

          var orgContext = Context.New(ContextKind.Of("organization"), "example-organization-key");

          var multiContext = Context.NewMulti(userContext, orgContext);
    ```
  </CodeGroup>

  <Note title="Interpreting custom attribute types">
    The optional name and kind attributes, which you can set with `.Name()` and `.Kind()`, expect string values. If the kind attribute is not specified, it is assumed to be "user." Other attribute values can be any JSON type, including booleans, numbers, strings, arrays, or objects. The SDK uses the [`LdValue`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/client/api/LaunchDarkly.Sdk.LdValue.html) type to represent arrays and objects. The client-side .NET SDK is strongly-typed, so be aware of this distinction.
  </Note>

  If an attribute is a JSON object, then in your flag or segment targeting, you can use `/` as a delimiter to refer to specific object fields. For example, if you have an "address" attribute that includes several fields, then you could use `/address/city` in your targeting. To learn more, read [Target with flags](/home/flags/target).

  To learn how to configure private attributes in the .NET (client-side) SDK, read [Private attributes](/sdk/features/private-attributes/client-side#net-client-side).

  To learn how to configure anonymous contexts in the .NET (client-side) SDK, read [Anonymous contexts and users](/sdk/features/anonymous#net-client-side).
</Accordion>

### Android

<Accordion title="Expand Android code sample">
  In the Android SDK, use a [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) to construct contexts. The argument to `builder` is the context's key. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example:

  <CodeGroup>
    ```java title="Android SDK v4.0+ (Java)" theme={null}
          LDContext context = LDContext.builder("example-context-key")
              .set("email", "sandy@example.com")
              .set("firstName", "Sandy")
              .set("lastName", "Smith")
              .set("group", "Global Health Services")
              .build();
    ```

    ```kotlin title="Android SDK v4.0+ (Kotlin)" theme={null}
          val context: LDContext = LDContext.builder("example-context-key")
              .set("email", "sandy@example.com")
              .set("firstName", "Sandy")
              .set("lastName", "Smith")
              .set("group", "Global Health Services")
              .build()
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```java title="Android SDK v4.0+" theme={null}
          LDContext context1 = LDContext.create(ContextKind.of("organization"), "example-organization-key");
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```java title="Android SDK v4.0+" theme={null}
          LDContext userContext = LDContext.create("example-user-key");
          LDContext deviceContext = LDContext.create(ContextKind.of("device"), "example-device-key");

          LDContext multiContext = LDContext.createMulti(
              userContext,
              deviceContext
          );
    ```
  </CodeGroup>

  <Note title="Interpreting custom attribute types">
    The optional name and kind attributes, which you can set with `.name()` and `.kind()`, expect string values. If the kind attribute is not specified, it is assumed to be "user." Other attribute values can be any JSON type, including boolean, number, string, array, or object. The Android SDK is strongly-typed, so be aware of this distinction.
  </Note>

  If an attribute is a JSON object, then in your flag or segment targeting, you can use `/` as a delimiter to refer to specific object fields. For example, if you have an "address" attribute that includes several fields, then you could use `/address/city` in your targeting. To learn more, read [Target with flags](/home/flags/target).

  To learn how to configure private attributes in the Android SDK, read [Private attributes](/sdk/features/private-attributes/client-side#android).

  To learn how to configure anonymous contexts in the Android SDK, read [Anonymous contexts and users](/sdk/features/anonymous#android).

  <Note title="`LDUser` removal">
    Version 4 of the Android SDK replaced users with contexts. Starting in version 5, the deprecated `LDUser` is removed. To learn more about replacing users with contexts, read the \[Android SDK 3.x to 4.0 migration guide]\(/sdk/client-side/android/migration-3-to-

    4. and [Best practices for upgrading users to contexts](/guides/flags/upgrading-contexts).
  </Note>
</Accordion>

### C++ (client-side)

<Accordion title="Expand C++ (client-side) code sample">
  In the C++ (client-side) SDK, you can construct a context using the `ContextBuilder`. The arguments to `.Kind()` are the context kind and key. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key, an email address, or a hash for the key, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example:

  <CodeGroup>
    ```cpp title="C++ SDK v3.0 (native)" theme={null}
          auto context = ContextBuilder()
            .Kind("user", "example-user-key")
            .Set("firstName", "Sandy")
            .Set("lastName", "Smith")
            .Set("groups", {"Acme", "Global Health Services"})
            .Build();
    ```

    ```c title="C++ SDK v3.0 (C binding)" theme={null}
          /* Ensure array_builder.h is included to enable building array values for the context */
          #include <launchdarkly/bindings/c/array_builder.h>

          LDContextBuilder context_builder = LDContextBuilder_New();
          LDContextBuilder_AddKind(context_builder, "user", "example-user-key");
          LDContextBuilder_Attributes_Set(context_builder, "user", "firstName", "Sandy");
          LDContextBuilder_Attributes_Set(context_builder, "user", "lastName", "Smith");

          LDArrayBuilder group_builder = LDArrayBuilder_New();
          LDArrayBuilder_Add(group_builder, LDValue_NewString("Acme"));
          LDArrayBuilder_Add(group_builder, LDValue_NewString("Global Health Services"));

          LDContextBuilder_Attributes_Set(context_builder, "user", "groups", LDArrayBuilder_Build(group_builder));

          LDContext context = LDContextBuilder_Build(context_builder);
    ```

    ```c title="C SDK v2.x (native)" theme={null}
          struct LDJSON *attributes, *groups;
          groups = LDNewArray();
          LDArrayPush(groups, LDNewText("Acme"));
          LDArrayPush(groups, LDNewText("Global Health Services"));
          attributes = LDNewObject();
          LDObjectSetKey("groups", groups);
          struct LDUser *user = LDUserNew("example-user-key");
          LDUserSetFirstName(user, "Sandy");
          LDUserSetLastName(user, "Smith");
          LDUserSetCustomAttributesJSON(user, attributes);
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```cpp title="C++ SDK v3.0 (native)" theme={null}
          auto context = ContextBuilder()
            .Kind("organization", "example-organization-key")
            .Build();
    ```

    ```c title="C++ SDK v3.0 (C binding)" theme={null}
          LDContextBuilder context_builder = LDContextBuilder_New();
          LDContextBuilder_AddKind(context_builder, "organization", "example-organization-key");

          LDContext context = LDContextBuilder_Build(context_builder);
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```cpp title="C++ SDK v3.0 (native)" theme={null}
          auto context = ContextBuilder()
            .Kind("user", "example-user-key")
            .Name("Sandy")
            .Kind("organization", "example-organization-key")
            .Name("Global Health Services")
            .Build();
    ```
  </CodeGroup>

  <Note title="Interpreting custom attribute types">
    The name and kind attributes, which you can set with `.Name()` and `.Kind()`, expect string values. Other attribute values can be any JSON type, including boolean, number, string, array, or object.
  </Note>

  To learn how to configure private attributes in the C++ (client-side) SDK, read [Private attributes](/sdk/features/private-attributes/client-side#c-client-side).

  To learn how to configure anonymous contexts in the C++ (client-side) SDK, read [Anonymous contexts and users](/sdk/features/anonymous#c-client-side).
</Accordion>

### Electron

<Accordion title="Expand Electron code sample">
  <Warning title="Electron SDK does not support contexts">
    The Electron SDK does not support contexts. Instead, it supports users. You can think of these as contexts with a context kind of "user." Other context kinds are not supported.
  </Warning>

  Here's an example of a user:

  <CodeGroup>
    ```js title="JavaScript" theme={null}
          const user = {
            key: 'example-user-key',
            firstName: 'Sandy',
            lastName: 'Smith',
            email: 'sandy@example.com',
            custom: {
              groups: ['Acme', 'Global Health Services']
            }
          };
    ```

    ```ts title="TypeScript" theme={null}
          import * as LDElectron from 'launchdarkly-electron-client-sdk';

          const user: LDElectron.LDUser = {
            key: 'example-user-key',
            firstName: 'Sandy',
            lastName: 'Smith',
            email: 'sandy@example.com',
            custom: {
              groups: ['Acme', 'Global Health Services'],
            },
          };
    ```
  </CodeGroup>

  The `key` property is the user's key. The key should uniquely identify each user. You can use a primary key or a hash, as long as the same user always has the same key. We recommend using a hash if possible. In this example, the hash is `"example-user-key"`.

  <Warning title="Personally-identifying user keys">
    By default, when the SDK requests feature flags from LaunchDarkly, it makes an HTTP GET request with the user properties encoded in the URL. If you do not want user keys or other properties to be in request URLs, enable the `useReport` option in your client configuration. The SDK sends user data in the body of an HTTP REPORT request instead.
  </Warning>

  <Note title="Interpreting custom attribute types">
    Most of the built-in attributes, like names and email addresses, expect string values. Custom attribute values can be booleans, numbers, strings, or arrays. If you enter a custom value on the **Users** list that looks like a number or a boolean, the SDK interprets it that way.
  </Note>

  To learn how to configure private attributes in the Electron SDK, read [Private attributes](/sdk/features/private-attributes/client-side#electron).

  To learn how to configure anonymous users in the Electron SDK, read [Anonymous contexts and users](/sdk/features/anonymous#electron).
</Accordion>

### Flutter

<Accordion title="Expand Flutter code sample">
  In the Flutter SDK, use a [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) to construct contexts. The arguments to `LDContextBuilder` are the context's kind and key. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example:

  <CodeGroup>
    ```dart title="Flutter SDK v4" theme={null}
          final context = LDContextBuilder()
            .kind('user', 'example-user-key')
            .setString('email', 'sandy@example.com')
            .setString('firstName', 'Sandy')
            .setString('lastName', 'Smith')
            .setString('group', 'microsoft')
            .build();
    ```

    ```dart title="Flutter SDK v2.x+" theme={null}
          LDContextBuilder builder = LDContextBuilder();
          builder.kind('user', 'example-user-key')
              .set('email', LDValue.ofString('sandy@example.com'))
              .set('firstName', LDValue.ofString('Sandy'))
              .set('lastName', LDValue.ofString('Smith'))
              .set('group', LDValue.ofString('microsoft'));

          LDContext context = builder.build();
    ```

    ```dart title="Flutter SDK v1.x" theme={null}
          LDUser user = LDUserBuilder('example-user-key')
              .email('sandy@example.com')
              .firstName('Sandy')
              .lastName('Smith')
              .custom('group', LDValue.ofString('microsoft'))
              .build();
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```dart title="Flutter SDK v4" theme={null}
          final context = LDContextBuilder()
            .kind('device', 'example-device-key')
            .build();
    ```

    ```dart title="Flutter SDK v2.x+" theme={null}
          LDContextBuilder builder = LDContextBuilder();
          builder.kind('device', 'example-device-key');
          LDContext context = builder.build();
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```dart title="Flutter SDK v4" theme={null}
          LDContextBuilder builder = LDContextBuilder();
          builder.kind('user', 'example-user-key')
            .name('Sandy');
          builder.kind('organization', 'example-organization-key')
            .name('Global Health Services');
          LDContext context = builder.build();
    ```

    ```dart title="Flutter SDK v2.x+" theme={null}
          LDContextBuilder builder = LDContextBuilder();
          builder.kind('user', 'example-user-key');
          builder.kind('device', 'example-device-key');
          LDContext context = builder.build();
    ```
  </CodeGroup>

  <Note title="Interpreting custom attribute types">
    The required `kind` and optional `name` attributes expect string values. Other attribute values can be any JSON type, including boolean, number, string, array, or object. Attribute values in the Flutter SDK use the `LDValue` class to support the various underlying types for the values. The Flutter SDK is strongly-typed, so be aware of this distinction.

    Starting in version 4, the Flutter SDK provides setters so that you do not have to create an `LDValue` yourself. Instead, you can use `setBool`, `setNum`, and `setString` when adding attributes to a context.
  </Note>

  To learn how to configure private attributes in the Flutter SDK, read [Private attributes](/sdk/features/private-attributes/client-side#flutter).

  To learn how to configure anonymous contexts in the Flutter SDK, read [Anonymous contexts and users](/sdk/features/anonymous#flutter).
</Accordion>

### iOS

<Accordion title="Expand iOS code sample">
  In the iOS SDK, you can construct a context using `LDContextBuilder`. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example:

  <CodeGroup>
    ```swift title="iOS SDK v8.0+ (Swift)" theme={null}
          var contextBuilder = LDContextBuilder(key: "example-user-key")
          contextBuilder.trySetValue("name", .string("Sandy"))
          contextBuilder.trySetValue("email", .string("sandy@example.com"))

          let context = try? contextBuilder.build().get()
    ```

    ```objectivec title="iOS SDK v8.0+ (Objective-C)" theme={null}
          LDContextBuilder *builder = [[LDContextBuilder alloc] initWithKey:@"example-user-key"];
          [builder trySetValueWithName:@"name" value:[LDValue ofString:@"Sandy"]];
          [builder trySetValueWithName:@"email" value:[LDValue ofString:@"sandy@example.com"]];

          LDContext *context = builder.build.success;
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```swift title="iOS SDK v8.0+ (Swift)" theme={null}
          var contextBuilder = LDContextBuilder(key: "example-organization-key")
          contextBuilder.kind("organization")

          let context = try? contextBuilder.build().get()
    ```

    ```objectivec title="iOS SDK v8.0+ (Objective-C)" theme={null}
          LDContextBuilder *builder = [[LDContextBuilder alloc] initWithKey:@"example-organization-key"];
          [builder kindWithKind:@"organization"];

          LDContext *context = builder.build.success;
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```swift title="iOS SDK v8.0+ (Swift)" theme={null}
          var userBuilder = LDContextBuilder(key: "example-user-key")
          var deviceBuilder = LDContextBuilder(key: "example-device-key")
          deviceBuilder.kind("device")

          var multiBuilder = LDMultiContextBuilder()
          multiBuilder.addContext(try userBuilder.build().get())
          multiBuilder.addContext(try deviceBuilder.build().get())

          let context = try multiBuilder.build().get()
    ```

    ```objectivec title="iOS SDK v8.0+ (Objective-C)" theme={null}
          LDContextBuilder *userBuilder = [[LDContextBuilder alloc] initWithKey:@"example-user-key"];
          LDContextBuilder *deviceBuilder = [[LDContextBuilder alloc] initWithKey:@"example-device-key"];
          [deviceBuilder kindWithKind:@"device"];

          LDMultiContextBuilder *multiBuilder = [[LDMultiContextBuilder alloc] init];
          [multiBuilder addContextWithContext:userBuilder.build.success];
          [multiBuilder addContextWithContext:deviceBuilder.build.success];

          LDContext *multiContext = multiBuilder.build.success;
    ```
  </CodeGroup>

  You can define additional attributes for a context by passing in a name and value for each. Additional attributes can be any JSON type, including boolean, number, string, array, or object.

  If an attribute is a JSON object, then in your flag or segment targeting, you can use `/` as a delimiter to refer to specific object fields. For example, if you have an "address" attribute that includes several fields, then you could use `/address/city` in your targeting. To learn more, read [Target with flags](/home/flags/target).

  To learn more about the specific context properties that are available in this SDK, read [`LDContextBuilder`](https://launchdarkly.github.io/ios-client-sdk/Structs/LDContextBuilder.html).

  To learn how to configure private attributes in the iOS SDK, read [Private attributes](/sdk/features/private-attributes/client-side#ios).

  To learn how to configure anonymous contexts in the iOS SDK, read [Anonymous contexts and users](/sdk/features/anonymous#ios).

  <Note title="`LDUser` removal">
    Version 8 of the iOS SDK replaced users with contexts. Starting in version 9, the deprecated `LDUser` is removed. To learn more about replacing users with contexts, read the iOS SDK 7.x to 8.0 migration guides for [Swift](/sdk/client-side/ios/migration-7-to-8-swift) or [Objective-C](/sdk/client-side/ios/migration-7-to-8-objc) and [Best practices for upgrading users to contexts](/guides/flags/upgrading-contexts).
  </Note>
</Accordion>

### Java

Script

<Accordion title="Expand JavaScript code sample">
  In the JavaScript SDK, construct a context using key/value pairs for the context attributes. Contexts use the `LDContext` type. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example of a context:

  <CodeGroup>
    ```js title="JavaScript SDK v3.x+" theme={null}
          const context = {
            kind: 'user',
            key: 'example-user-key',
            firstName: 'Sandy',
            lastName: 'Smith',
            email: 'sandy@example.com',
            groups: ['Acme', 'Global Health Services']
          };
    ```

    ```ts title="JavaScript SDK v3.x+ (TypeScript)" theme={null}
          import * as ld from 'launchdarkly-js-client-sdk';

          const context: ld.LDContext = {
            kind: 'user',
            key: 'example-user-key',
            firstName: 'Sandy',
            lastName: 'Smith',
            email: 'sandy@example.com',
            groups: ['Acme', 'Global Health Services']
          }
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```js title="JavaScript SDK v3.x+" theme={null}
          const context = {
            kind: 'organization',
            key: 'example-organization-key'
          };
          const client = LDClient.initialize('example-client-side-id', context);

          try {
            await client.waitForInitialization(5);
            proceedWithSuccessfullyInitializedClient();
          } catch(err) {
            // Client failed to initialized or timed out
            // variation() calls return fallback values until initialization completes
          }
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```js title="JavaScript SDK v3.x+" theme={null}
          const deviceContext = {
            kind: 'device',
            type: 'iPad',
            key: 'example-device-key'
          }

          const userContext = {
            kind: 'user',
            key: 'example-user-key',
            name: 'Sandy',
            role: 'doctor'
          }

          const multiContext = {
            kind: 'multi',
            user: userContext,
            device: deviceContext
          }

          const client = LDClient.initialize('example-client-side-id', multiContext)

          try {
            await client.waitForInitialization(5);
            proceedWithSuccessfullyInitializedClient();
          } catch(err) {
            // Client failed to initialized or timed out
            // variation() calls return fallback values until initialization completes
          }
    ```
  </CodeGroup>

  <Note title="Interpreting custom attribute types">
    The optional `name` and `kind` attributes expect string values. If the `kind` attribute is not specified, it is assumed to be "user." Other attributes can be booleans, numbers, strings, arrays, or JSON objects.
  </Note>

  If an attribute is a JSON object, then in your flag or segment targeting, you can use `/` as a delimiter to refer to specific object fields. For example, if you have an "address" attribute that includes several fields, then you could use `/address/city` in your targeting. To learn more, read [Target with flags](/home/flags/target).

  <Warning title="Personally-identifying context keys">
    We recommend against using personally identifiable information (PII) in context keys. If the `key` attribute you rely on in your context JSON does contain PII, you should enable the `useReport` option by sending the evaluation context as a JSON base64 URL-encoded path parameter. When you enable `useReport`, the SDK fetches flag settings by sending the context JSON in the body of a REPORT request instead, hiding that information from request logs.
  </Warning>

  To learn how to configure private attributes in the JavaScript SDK, read [Private attributes](/sdk/features/private-attributes/client-side#javascript).

  To learn how to configure anonymous contexts in the JavaScript SDK, read [Anonymous contexts and users](/sdk/features/anonymous#javascript).
</Accordion>

### Node.js (client-side)

<Accordion title="Expand Node.js (client-side) code sample">
  In the Node.js (client-side) SDK, construct a context using key/value pairs for the context attributes. Contexts use the `LDContext` type. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example of a context:

  <CodeGroup>
    ```js title="Node.js SDK v3.0 (JavaScript)" theme={null}
          const context = {
            kind: 'user',
            key: 'example-user-key',
            firstName: 'Sandy',
            lastName: 'Smith',
            email: 'sandy@example.com',
            groups: ['Acme', 'Global Health Services']
          };
    ```

    ```ts title="Node.js SDK v3.0 (TypeScript)" theme={null}
          import * as ld from 'launchdarkly-node-client-sdk';

          const context: ld.LDContext = {
            kind: 'user',
            key: 'example-user-key',
            firstName: 'Sandy',
            lastName: 'Smith',
            email: 'sandy@example.com',
            groups: ['Acme', 'Global Health Services']
          };
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```js title="Node.js SDK v3.0 (JavaScript)" theme={null}
          const context = {
            kind: 'organization',
            key: 'example-organization-key'
          };
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```js title="Node.js SDK v3.0 (JavaScript)" theme={null}
          const deviceContext = {
            kind: 'device',
            type: 'iPad',
            key: 'example-device-key'
          }

          const userContext = {
            kind: 'user',
            key: 'example-user-key',
            name: 'Sandy',
            role: 'doctor'
          }

          const multiContext = {
            kind: 'multi',
            user: userContext,
            device: deviceContext
          }
    ```
  </CodeGroup>

  The `kind` and `name` attributes expect string values. Other attribute values can be booleans, numbers, strings, arrays, or JSON objects.

  If an attribute is a JSON object, then in your flag or segment targeting, you can use `/` as a delimiter to refer to specific object fields. For example, if you have an "address" attribute that includes several fields, then you could use <code>/address/city</code> in your targeting. To learn more, read [Target with flags](/home/flags/target).

  <Warning title="Personally-identifying keys">
    By default, when the SDK requests feature flags from LaunchDarkly, it makes an HTTP GET request with the user properties encoded in the URL. If you do not want keys or other properties to be in request URLs, enable the `useReport` option in your client configuration. The SDK sends data in the body of an HTTP REPORT request instead.
  </Warning>

  To learn how to configure private attributes in the Node.js (client-side) SDK, read [Private attributes](/sdk/features/private-attributes/client-side#nodejs-client-side).

  To learn how to configure anonymous contexts in the Node.js (client-side) SDK, read [Anonymous contexts and users](/sdk/features/anonymous#nodejs-client-side).
</Accordion>

### React Native

<Accordion title="Expand React Native code sample">
  In the React Native SDK, construct a context using key/value pairs for the context attributes. Contexts use the `LDContext` type.

  The first attribute in the object is the `key`. In the React Native SDK, both `key` and `kind` are required. They are the only mandatory attributes. The combination of key and kind must uniquely identify each context. You can use any value for the key, such as a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example:

  <CodeGroup>
    ```ts title="React Native SDK v10" theme={null}
          import { type LDContext } '@launchdarkly/react-native-client-sdk';

          // key and kind are the only required attributes

          let context: LDContext = {
            key: 'example-user-key',
            kind: 'user',
            firstName: 'Sandy',
            lastName: 'Smith',
            email: 'sandy@example.com',
            address: {
              street: '123 Main St',
              city: 'Springfield'
            }
          };
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```js title="React Native SDK v10" theme={null}
          const context = {
            kind: 'organization',
            key: 'example-organization-key'
          };
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```ts title="React Native SDK v10" theme={null}
          const deviceContext = {
            kind: 'device',
            key: 'example-device-key'
          };

          const userContext = {
            kind: 'user',
            key: 'example-user-key',
            name: 'Sandy',
            role: 'doctor'
          };

          const multiContext = {
            kind: 'multi',
            user: userContext,
            device: deviceContext
          }
    ```
  </CodeGroup>

  If the context is anonymous, you should set the `key` to an empty string. The SDK will automatically set the key to a LaunchDarkly-specific, device-unique string that is consistent between app restarts and device reboots.

  Other attributes can be booleans, numbers, strings, arrays, or JSON objects.

  If an attribute is a JSON object, then in your flag or segment targeting, you can use `/` as a delimiter to refer to specific object fields. For example, if you have an "address" attribute that includes several fields, then you could use `/address/city` in your targeting. To learn more, read [Target with flags](/home/flags/target).

  To learn how to configure private attributes in the React Native SDK, read [Private attributes](/sdk/features/private-attributes/client-side#react-native).

  To learn how to configure anonymous contexts in the React Native SDK, read [Anonymous contexts and users](/sdk/features/anonymous#react-native).
</Accordion>

### React Web

All context-related functionality provided by the [JavaScript SDK](#javascript) is also available in the React Web SDK.

Unlike the JavaScript SDK, the React Web SDK does not require a context object for initialization. If you do not specify one, the React SDK uses an anonymous context by default.

### Roku

<Accordion title="Expand Roku code sample">
  In the Roku SDK, use `LaunchDarklyCreateContext` to construct a context. The combination of key and kind must uniquely identify each context. For the key, you can use a primary key or a hash, as long as the same context always has the same key. We recommend using a hash if possible.

  Here's an example:

  <CodeGroup>
    ```brightscript title="Roku SDK v2.0 (BrightScript)" theme={null}
          context = LaunchDarklyCreateContext({"key": "example-user-key", "kind": "user"})
    ```

    ```brightscript title="Roku SDK v1.x (BrightScript)" theme={null}
          user = LaunchDarklyUser("example-user-key")
    ```
  </CodeGroup>

  Here's how to construct a context with a context kind of something other than "user":

  <CodeGroup>
    ```brightscript title="Roku SDK v2.0 (BrightScript)" theme={null}
          context = LaunchDarklyCreateContext({"key": "example-organization-key", "kind": "organization"})
    ```
  </CodeGroup>

  Here's how to construct a multi-context, which includes multiple context kinds:

  <CodeGroup>
    ```brightscript title="Roku SDK v2.0 (BrightScript)" theme={null}
          context = LaunchDarklyCreateContext({
              "kind": "multi",
              "user": { "key": "example-user-key", "name": "Sandy" },
              "org": { "key": "org-key-789xyz", "name": "LaunchDarkly" }
          })
    ```
  </CodeGroup>

  <Note title="Interpreting custom attribute types">
    The optional `name` and `kind` attributes expect string values. If the `kind` attribute is not specified, it is assumed to be "user." Other attributes can be booleans, numbers, strings, arrays, or JSON objects.
  </Note>

  If an attribute is a JSON object, then in your flag or segment targeting, you can use `/` as a delimiter to refer to specific object fields. For example, if you have an "address" attribute that includes several fields, then you could use `/address/city` in your targeting. To learn more, read [Target with flags](/home/flags/target).

  To learn how to configure private attributes in the Roku SDK, read [Private attributes](/sdk/features/private-attributes/client-side#roku).

  To learn how to configure anonymous contexts in the Roku SDK, read [Anonymous contexts and users](/sdk/features/anonymous#roku).
</Accordion>
