Skip to main content

Targeting Users and Controlling Assignments

Not every experiment should run for every user. Sometimes you want to target specific browsers, geographies, or user segments. Other times you need to override which variant a user sees for development, QA, or API-driven personalization.

This page covers three related features. Jump to the one you need:

  • Attributes - pass user metadata so you can create audience segments in the Web Console
  • Custom assignments - programmatically choose which variant a user sees (counted as real data)
  • Overrides - force a variant for testing without affecting experiment statistics
Key difference: custom assignments vs overrides

Custom assignments are counted as real experiment data. Use them when an external system (ML model, third-party targeting) decides the variant and you want those users in your analysis. Overrides are ignored by the statistics engine. Use them for development and QA.

Passing user attributes for targeting

Attributes are metadata about the user or request. Once you pass them to the SDK, you can use them in the Web Console to create audience segments that control who enters an experiment.

A common example: you're running an experiment only for mobile users. Pass the user_agent attribute and the SDK will automatically parse it into browser, OS, and device attributes that you can filter on in the Web Console.

Other useful attributes might include:

  • Geographic data like country or region
  • Account properties like subscription tier or account age
  • Request metadata like referrer or landing page

Set attributes using the attribute() or attributes() methods, before or after the context is ready.

A particularly useful attribute is user_agent. When you pass it to the SDK, ABsmartly automatically parses it into browser, OS, and device attributes that you can use for targeting in the Web Console. See Segments in Dashboard Settings for details.

context.attribute("user_agent", navigator.userAgent);

context.attributes({
customer_time:
user.created > new Date().getTime() - 24 * 60 * 60 * 1000
? "new_customer"
: "returning_customer",
user_type: user.isInternal ? "internal" : "normal",
url: location.toString(),
user_agent: navigator.userAgent,
referrer: document.referrer,
screenName,
pageName,
country: headers["HTTP_CF_IPCOUNTRY"],
language: headers["Accept-Language"],
channel: query_params.utm_medium,
});
caution

You should create audiences with the same attributes as those in the Web Console. By default it will not enforce these conditions, but if for some reason the treatment() method is called for a user that doesn’t meet the correct criteria, the Web Console will warn you about it.

Custom assignments

Sometimes you need to control which variant a user gets based on external logic. Maybe your recommendation engine determines the best variant, or you're integrating with a third-party targeting system that provides variant selections.

Custom assignments let you do this. A few real scenarios:

  • ML-driven variant selection. Your model predicts which variant performs best for each user segment, and you feed that into ABsmartly.
  • Third-party targeting integration. An external system decides the allocation, and you pass it through to ABsmartly for tracking.
  • Geography-based logic. An API call determines the user's region, and you assign variants accordingly.
Important distinction

Custom assignments are counted as real experiment data. ABsmartly's statistics engine will include these users in the analysis. If you just need to force a variant for development or QA, use overrides instead.

Set a variant for a single experiment, or use the batch method for multiple experiments at once. Both can be called before or after the context is ready.

const chosenVariant = 1;

context.customAssignment("experiment_name", chosenVariant);

For multiple experiments:

const assignments = {
experiment_name: 1,
another_experiment_name: 0,
a_third_experiment_name: 2,
};

context.customAssignments(assignments);
danger

Events with custom assignments are counted as eligible events by the ABsmartly statistics engines. If you are using these methods for development purposes (to force a particular variant for yourself or somebody else on the team) you probably need overrides instead.

Overriding variants for development and QA

During development and QA, you need to see specific variants without polluting your experiment data. Overrides solve this. They force a particular variant for a user, but the event is marked as ineligible and completely ignored by ABsmartly's statistics engine.

Use overrides when:

  • You're developing a new variant and need to see it in your local environment
  • QA is testing each variant before the experiment goes live
  • A stakeholder wants a demo of a specific variant
danger

Overridden events are marked as ineligible and completely ignored by ABsmartly's statistics engine. If you need the event to count as real data, use custom assignments instead, though this is rarely what you want for QA.

Override methods force a specific variant. They can be called before the context is ready.

context.override("exp_test_experiment", 1); // force variant 1 of treatment
context.overrides({
exp_test_experiment: 1,
exp_another_experiment: 0,
});

Overriding Based On URL Params

The most common use case for overriding is to override a treatment based on params in the URL. This allows for greater flexibility in the development and QA stages. The following Javascript function can be ported to any language and used to parse the URL query parameters and return an object of overrides. This object can then be passed to the overrides() context method to force a particular variant for one or multiple experiment(s).

Prefixes

Here we using absmartly_ as a prefix for the query parameters, but you can use whatever prefix you like. It could be exp_, test_, or even a simple _!

function getABsmartlyOverridesFromQuery(req) {
const overrides = {};

// Iterate through all query parameters
for (const [key, value] of Object.entries(req.query)) {
// Check if the query parameter starts with "absmartly_"
if (key.startsWith('absmartly_')) {
// Extract the experiment name (remove "absmartly_" prefix)
const experimentName = key.slice('absmartly_'.length);

// Convert the value to a number if possible, otherwise keep it as a string
const variantValue = isNaN(value) ? value : Number(value);

// Add to overrides object
overrides[experimentName] = variantValue;
}
}

return overrides;
}