Using Variables to Drive Logic
Using variables ensures that variation name is not required
Using Variables to Drive Logic Instead of Returning Variation Names in VWO FE
Why Variables Over Direct Variation Returns?
When running experiments or feature rollouts with VWO Feature Experimentation (FE), you typically need to change behavior or configuration based on the variation assigned to a user. One approach is to check the variation name returned by VWO and hard-code behavior in your application. However, this quickly leads to tightly coupled logic, hard-to-maintain code, and rigid experiment evolution.
Instead, centralizing configuration via feature variables makes your code:
- Data-driven: No hard-coded variation names in app logic.
- Flexible: Change behaviour by updating variable values in the VWO dashboard only.
- Extensible: Add or evolve variations without code changes.
Variables are first-class concepts in VWO FME — they let you attach typed values (Boolean, text, number, JSON) to a feature flag. Each variation then defines variable values for that feature.
How VWO Feature Experimentation Works
In VWO FE:
- You create a feature flag in the VWO dashboard and define one or more variables for it.
- You create variations of that flag, where each variation assigns specific values to those variables.
- You configure rules (rollouts, experimentation, personalization) that determine which users should see which variation.
- In your code, you fetch the flag and then access variable values for the assigned variation.
This model decouples what the code does from how it’s configured.
Typical Node.js SDK Flow (Without Variables)
Here’s how many teams first implement a feature test:
const flag = await vwoClient.getFlag('feature_key', userContext);
// What variation was assigned?
const variation = flag.isEnabled() ? flag.getVariable('variationName') : null;
// Branch directly on variation name
if (variation === 'Variation A') {
// Do something
} else if (variation === 'Variation B') {
// Do something else
} else {
// Control or fallback
}While workable, this tightly couples your application logic to variation names. If you rename a variation or add a third one, you must change the code.
The Better Pattern: Use Variables
Instead of returning or comparing variation strings, define variables for all controlled behavior. For example:
Step 1 — Define Variables in VWO
In the VWO dashboard for your feature flag:
| Variable Key | Type | Meaning |
buttonText | String | Label text for a button |
showNewFlow | Boolean | Whether to use the new user flow |
discountPercentage | Number | Discount value |
Assign values across variations:
| Variation | buttonText | showNewFlow | discountPercentage |
| Control | “Buy Now” | false | 0 |
| Variation_A | “Get Deal” | true | 10 |
| Variation_B | “Claim Discount” | true | 15 |
Now behavior is driven by data, not string matching.
Step 2 — Access Variables in Code
const flag = await vwoClient.getFlag('feature_key', userContext);
if (flag.isEnabled()) {
// Fetch individual variables
const buttonText = flag.getVariable('buttonText', 'Buy Now'); // fallback default
const showNewFlow = flag.getVariable('showNewFlow', false);
const discount = flag.getVariable('discountPercentage', 0);
// Use them in your app logic
renderButton(buttonText);
if (showNewFlow) {
runNewSignupFlow(discount);
} else {
runLegacyFlow();
}
} else {
renderLegacyUI();
}Benefits of This Pattern
- No dependency on variation names — Your app logic adapts to variable values only.
- Easier experiment evolution — Add or change variation values without touching code.
- Single source of truth — All behavioral configuration lives in VWO.
- Better telemetry & experimentation — You can measure metric impact on variables directly.
Accessing the Variation Name (When You Really Need It)
There are valid scenarios where teams want to know which variation was assigned, for example:
- Logging or analytics enrichment
- Debugging experiment behavior
- Integrating with downstream systems that expect a label
VWO FE intentionally avoids exposing variation names as a first-class runtime dependency, to discourage tight coupling. Instead, the recommended approach is: Expose the variation name explicitly as a variable.
Recommended Pattern: variation_name Variable
variation_name VariableDefine a variable such as:
| Variable Key | Type | Purpose |
variation_name | String | Human-readable identifier for the variation |
Assign values per variation:
| Variation | variation_name |
| Control | control |
| Variation_A | new_flow_v1 |
| Variation_B | new_flow_v2 |
Accessing It in Code
const flag = await vwoClient.getFlag('feature_key', userContext);
if (flag.isEnabled()) {
const variationName = flag.getVariable('variation_name', 'control');
logger.info('User assigned variation:', variationName);
// Still use variables for behavior
}
Why This Is the Right Approach in VWO FE
From a VWO Feature Experimentation product design perspective:
- Variations are configuration artifacts, not runtime contracts
- Variables are the explicit API surface exposed to applications
- Making variation identity a variable ensures:
- Controlled exposure
- Backward compatibility
- Safe refactoring of experiments
This approach also aligns with OpenFeature-style best practices, where flag evaluation returns values, not experiment structure.
Using JSON Variables for Complex Config
If you have many related configuration parameters, using JSON variables can be even more powerful:
{
"uiConfig": {
"theme": "dark",
"layout": "compact",
"ctaColors": { "bg":"#F00", "text":"#FFF" }
},
"threshold": 45
}
This pattern is especially useful for dynamic values and feature parameter sets that go beyond simple booleans and strings.
const config = flag.getVariable('config', { uiConfig: {}, threshold: 0 });
// Use config.uiConfig and config.threshold in your logic
applyUIConfig(config.uiConfig);Summary
Using variables instead of branching directly on variation names:
- Makes your codebase more maintainable
- Lets non-devs iterate on experiments without code changes
- Avoids logic sprawl tied to variation identifiers
- Supports richer experiment configurations via types and JSON
Updated about 13 hours ago
