From 480fea0fa1d8e157147b3184f93a698722bcea08 Mon Sep 17 00:00:00 2001 From: vanshiz Date: Wed, 20 May 2026 06:07:10 +0530 Subject: [PATCH 1/4] docs: add experimentation-focused examples to tracking doc Signed-off-by: vanshiz --- docs/reference/concepts/07-tracking.mdx | 132 ++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/docs/reference/concepts/07-tracking.mdx b/docs/reference/concepts/07-tracking.mdx index 468c68fbc..db717c505 100644 --- a/docs/reference/concepts/07-tracking.mdx +++ b/docs/reference/concepts/07-tracking.mdx @@ -109,3 +109,135 @@ client.Track( + +## Experimentation-Focused Example + +Here is a complete A/B testing flow using OpenFeature. +The pattern is: evaluate a flag to assign the user to a variant, show the corresponding experience, then call `track` when the conversion event occurs. +The provider automatically links the tracking event back to the flag evaluation context (including the `targetingKey`), so your analytics platform can segment results by variant. + + + +```ts +import { OpenFeature } from '@openfeature/server-sdk'; + +// Set evaluation context with the user's targeting key. +// The targeting key is how your provider buckets users into variants consistently. +OpenFeature.setContext({ + targetingKey: 'user-123', +}); + +const client = OpenFeature.getClient(); + +// Evaluate the experiment flag — provider returns true (variant) or false (control) +const useNewCheckout = await client.getBooleanValue('checkout-experiment', false); + +if (useNewCheckout) { + // Show the new checkout UI (variant group) + await showNewCheckout(); +} else { + // Show the existing checkout UI (control group) + await showExistingCheckout(); +} + +// When the user completes the purchase, emit a tracking event. +// The provider associates this event with the flag evaluation context automatically. +client.track('checkout-completed', { value: 49.99, currencyCode: 'USD' }); +``` + + + +```java +import dev.openfeature.sdk.*; + +OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + +// Set evaluation context with the user's targeting key +Map attrs = new HashMap<>(); +EvaluationContext ctx = new ImmutableContext("user-123", attrs); +api.setEvaluationContext(ctx); + +Client client = api.getClient(); + +// Evaluate the experiment flag +Boolean useNewCheckout = client.getBooleanValue("checkout-experiment", false); + +if (useNewCheckout) { + showNewCheckout(); +} else { + showExistingCheckout(); +} + +// Track the conversion event — provider links it back to the flag evaluation context +client.track("checkout-completed", new MutableTrackingEventDetails(49.99).add("currencyCode", "USD")); +``` + + + +```csharp +using OpenFeature; +using OpenFeature.Model; + +// Set evaluation context with the user's targeting key +EvaluationContextBuilder builder = EvaluationContext.Builder(); +builder.Set("targetingKey", "user-123"); +EvaluationContext ctx = builder.Build(); +Api.Instance.SetContext(ctx); + +var client = Api.Instance.GetClient(); + +// Evaluate the experiment flag — all evaluations are async in .NET SDK, note GetBooleanValueAsync +var useNewCheckout = await client.GetBooleanValueAsync("checkout-experiment", false); + +if (useNewCheckout) { + await ShowNewCheckout(); +} else { + await ShowExistingCheckout(); +} + +// Track the conversion event +client.Track("checkout-completed", trackingEventDetails: new TrackingEventDetailsBuilder() + .SetValue(49.99).Set("currencyCode", "USD").Build()); +``` + + + +```go +import ( + "context" + "github.com/open-feature/go-sdk/openfeature" +) + +// Set evaluation context with the user's targeting key +openfeature.SetEvaluationContext( + openfeature.NewEvaluationContext( + "user-123", + map[string]any{}, + ), +) + +client := openfeature.NewClient("my-app") + +// Evaluate the experiment flag +useNewCheckout, _ := client.BooleanValue( + context.TODO(), "checkout-experiment", false, openfeature.EvaluationContext{}, +) + +if useNewCheckout { + showNewCheckout() +} else { + showExistingCheckout() +} + +// Track the conversion event — provider links it back to the flag evaluation context +client.Track( + context.TODO(), + "checkout-completed", + openfeature.EvaluationContext{}, + openfeature.NewTrackingEventDetails(49.99).Add("currencyCode", "USD"), +) +``` + + + + From 481fb01e77579a3a8f53cf6ef015548608224332 Mon Sep 17 00:00:00 2001 From: vanshiz Date: Wed, 20 May 2026 06:32:36 +0530 Subject: [PATCH 2/4] docs: add experimentation concepts page Signed-off-by: vanshiz --- .../reference/concepts/08-experimentation.mdx | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 docs/reference/concepts/08-experimentation.mdx diff --git a/docs/reference/concepts/08-experimentation.mdx b/docs/reference/concepts/08-experimentation.mdx new file mode 100644 index 000000000..35915bfb6 --- /dev/null +++ b/docs/reference/concepts/08-experimentation.mdx @@ -0,0 +1,261 @@ +--- +sidebar_position: 8 +id: experimentation +--- + +# Experimentation + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +OpenFeature provides built-in support for experimentation use cases such as A/B testing, multivariate tests, and gradual rollouts. +This page explains how three existing capabilities namely the tracking API, hooks, and targeting key, work together to support experimentation workflows. + +## How OpenFeature Supports Experimentation + +Three OpenFeature mechanisms combine to form a complete experimentation pipeline: + +- **Tracking API** : Records business events (conversions, clicks, sign-ups) and links them back to the flag evaluation context so your analytics platform can measure per-variant outcomes. +- **Hooks** : Extend the SDK at well-defined points of the flag evaluation lifecycle to capture metrics and forward data to analytics platforms without modifying application code. +- **Targeting Key** : A stable user identifier (passed via evaluation context) that your provider uses to assign users to variants consistently across sessions, and that analytics platforms use as the join key between flag evaluations and tracking events. + + +```mermaid +sequenceDiagram + participant App + participant OpenFeature SDK + participant Flag Provider + + App->>OpenFeature SDK: setContext(targetingKey, attributes) + App->>OpenFeature SDK: getBooleanValue("checkout-experiment", false) + OpenFeature SDK->>Flag Provider: resolve flag for targetingKey + Flag Provider-->>OpenFeature SDK: variant (true / false) + OpenFeature SDK-->>App: variant value + App->>App: render variant UI + App->>OpenFeature SDK: track("checkout-completed", details) + OpenFeature SDK->>Flag Provider: forward tracking event + Note over Flag Provider: Provider forwards data to your
configured analytics platform +``` + +## Experimentation Workflow + +### Step 1 : Set the Evaluation Context + +The `targetingKey` is the user identifier your provider uses to assign the user to a variant consistently across sessions. +Additional attributes (plan, geo, device) can be used by the provider for more advanced targeting rules. + + + + +```ts +import { OpenFeature } from '@openfeature/server-sdk'; + +// Set global context — targetingKey is the primary experiment identifier +OpenFeature.setContext({ + targetingKey: 'user-456', + plan: 'premium', + geo: 'EU', +}); +``` + + + + + +```java +import dev.openfeature.sdk.*; +import java.util.HashMap; +import java.util.Map; + +OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + +// Build evaluation context with targeting key and attributes +Map attrs = new HashMap<>(); +attrs.put("plan", new Value("premium")); +attrs.put("geo", new Value("EU")); +EvaluationContext ctx = new ImmutableContext("user-456", attrs); + +api.setEvaluationContext(ctx); +``` + + + + + +```csharp +using OpenFeature; +using OpenFeature.Model; + +// Build evaluation context with targeting key and attributes +EvaluationContextBuilder builder = EvaluationContext.Builder(); +builder.Set("targetingKey", "user-456"); +builder.Set("plan", "premium"); +builder.Set("geo", "EU"); +EvaluationContext ctx = builder.Build(); + +Api.Instance.SetContext(ctx); +``` + + + + + +```go +import "github.com/open-feature/go-sdk/openfeature" + +// Set global context with targeting key and attributes +openfeature.SetEvaluationContext( + openfeature.NewEvaluationContext( + "user-456", + map[string]any{ + "plan": "premium", + "geo": "EU", + }, + ), +) +``` + + + + +### Step 2 : Evaluate the Experiment Flag + +Use the standard evaluation API to determine which variant the user receives. +The provider uses the `targetingKey` from the context to return a consistent variant for that user. + + + + +```ts +const client = OpenFeature.getClient(); + +// getBooleanValue: false = control group, true = variant group +const useNewCheckout = await client.getBooleanValue('checkout-experiment', false); + +if (useNewCheckout) { + renderNewCheckoutFlow(); +} else { + renderExistingCheckoutFlow(); +} +``` + + + + + +```java +Client client = api.getClient(); + +// getBooleanValue: false = control, true = variant +Boolean useNewCheckout = client.getBooleanValue("checkout-experiment", false); + +if (useNewCheckout) { + renderNewCheckoutFlow(); +} else { + renderExistingCheckoutFlow(); +} +``` + + + + + +```csharp +var client = Api.Instance.GetClient(); + +// GetBooleanValueAsync: false = control, true = variant +var useNewCheckout = await client.GetBooleanValueAsync("checkout-experiment", false); + +if (useNewCheckout) { + RenderNewCheckoutFlow(); +} else { + RenderExistingCheckoutFlow(); +} +``` + + + + + +```go +client := openfeature.NewClient("my-app") + +// BooleanValue: false = control, true = variant +useNewCheckout, _ := client.BooleanValue( + context.TODO(), "checkout-experiment", false, openfeature.EvaluationContext{}, +) + +if useNewCheckout { + renderNewCheckoutFlow() +} else { + renderExistingCheckoutFlow() +} +``` + + + + +### Step 3 : Track Conversions + +Call `track` when a business event occurs (purchase, sign-up, click). +The provider automatically links this event to the flag evaluation context — including the `targetingKey` — so your analytics platform can segment conversion rates by variant. + + + + +```ts +// When the user completes a purchase, emit a tracking event +client.track('checkout-completed', { value: 29.99, currencyCode: 'USD' }); +``` + + + + + +```java +// When the user completes a purchase, emit a tracking event +client.track("checkout-completed", + new MutableTrackingEventDetails(29.99).add("currencyCode", "USD")); +``` + + + + + +```csharp +// When the user completes a purchase, emit a tracking event +client.Track("checkout-completed", trackingEventDetails: new TrackingEventDetailsBuilder() + .SetValue(29.99).Set("currencyCode", "USD").Build()); +``` + + + + + +```go +// When the user completes a purchase, emit a tracking event +client.Track( + context.TODO(), + "checkout-completed", + openfeature.EvaluationContext{}, + openfeature.NewTrackingEventDetails(29.99).Add("currencyCode", "USD"), +) +``` + + + + +### Step 4 : Analyze Results + +Your analytics platform uses the `targetingKey` as the join key between flag evaluation data and tracking events. +This lets it compute per-variant conversion rates and determine statistical significance, so you can decide whether to roll out the winning variant. + +## The Targeting Key + +The `targetingKey` is the single most important field for experimentation. It serves three roles: + +- **Consistent assignment** : The same user always receives the same variant as long as the flag configuration does not change. +- **Unbiased splits** : Providers use consistent hashing on the targeting key to distribute users evenly across variants. +- **Join key** : Analytics platforms join flag evaluation records with tracking events using this identifier. + +Use a stable, unique user identifier as the targeting key — typically a user ID, session ID, or device ID. From 5b4678f682361980e6e7d1a1e96ef60dd05322b9 Mon Sep 17 00:00:00 2001 From: vanshiz Date: Wed, 20 May 2026 06:48:47 +0530 Subject: [PATCH 3/4] docs: add experimentation section to intro page Signed-off-by: vanshiz --- docs/reference/intro.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/reference/intro.mdx b/docs/reference/intro.mdx index 39a6c481f..a919a2e7d 100644 --- a/docs/reference/intro.mdx +++ b/docs/reference/intro.mdx @@ -84,6 +84,14 @@ Providers might wrap a vendor SDK, call a bespoke flag evaluation REST API, or e [Hooks](./concepts/04-hooks.mdx) are a mechanism that allow for the addition of arbitrary behavior at various points in the _flag evaluation life-cycle_. Hooks let you extend the OpenFeature SDK, adding functionality such as validating a resolved flag value, modifying or adding data to the evaluation context, logging, telemetry, and tracking. +### Experimentation + +OpenFeature includes support for [experimentation](./concepts/08-experimentation.mdx) use cases. +The [tracking API](./concepts/07-tracking.mdx) lets you associate user actions (conversions, clicks, sign-ups) with flag evaluations, +enabling A/B testing and other experimentation workflows. +Combined with the [evaluation context](./concepts/03-evaluation-context.mdx) (targeting key, user attributes) and [hooks](./concepts/04-hooks.mdx) +for custom metrics, OpenFeature provides a complete experimentation pipeline that works with any analytics platform. + ### Events [Events](./concepts/05-events.mdx) enable the ability to react to state changes in the provider or underlying flag management system. From f2e392f87b8ee90823c54633e7b8b76e0ba321fc Mon Sep 17 00:00:00 2001 From: vanshiz Date: Wed, 20 May 2026 06:49:42 +0530 Subject: [PATCH 4/4] feat: add experimentation use case to homepage features section Signed-off-by: vanshiz --- src/partials/features-zigzag.tsx | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/partials/features-zigzag.tsx b/src/partials/features-zigzag.tsx index 90f771f23..0c240d46e 100644 --- a/src/partials/features-zigzag.tsx +++ b/src/partials/features-zigzag.tsx @@ -223,6 +223,48 @@ function FeaturesZigZag() { +
+
+
+ !provider.excludeFromLandingPage).map((provider) => ({ + key: `exp-provider-${provider.name}`, + name: provider.name, + logo: provider.logo, + href: encodeURI(`/ecosystem?instant_search[refinementList][vendor][0]=${provider.name}`), + }))} + /> +
+
+
+
+
+ Data-driven decisions +
+

Built for experimentation

+

+ Run A/B tests and measure feature impact without changing your stack. +

+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+