# A/B test

### A/B testing in Blings MP5 (variants via SDK + UTM for analytics)

This page explains a simple, reliable way to run an A/B (or A/B/C…) test in Blings MP5 by:

1. Picking a variant from URL if provided, otherwise select randomly
2. Passing it into the MP5 data fields (so Studio/Flow can react to it)
3. Persisting it into UTM parameters for analytics/BI.
4. Store it in localStorage so refresh will show the same version

***

#### Full demo code

Copy the code below to Blings Platform ⇒ Integration ⇒ "advanced" code&#x20;

```javascript

// Test #1 (you can add multiple)
runStickyABTest(params, {
  testName: "abtest1", // <<=== Update with your variable name. 
  // Make sure to create the variable in the data-schema inside Blings Studio or Platform->settings page
  variants: ["10off", "free-trial", "summer-promotion"], // <<=== Replace with the A/B options
  utmSlot: "utm_source", // <<=== pick an available UTM slot, or leave it empty
});


// COPY ONCE
/**
   ===========================
   Blings Sticky A/B Tests
   ===========================
 * Runs one sticky A/B test.
 * - If params.data[testName] already exists (and valid), it will be saved (stickied).
 * - Else it will reuse localStorage if available.
 * - Else it randomly picks one, saves it, and writes it into params.data[testName].
 * - Always mirrors result into params.utmParams[utmSlot] for BI.
 */
function runStickyABTest(params, { testName, variants, utmSlot }) {
  params = params || {};
  params.data = params.data || {};
  params.utmParams = params.utmParams || {};

  const key = `blings_${testName}`;
  const pick = () => variants[Math.floor(Math.random() * variants.length)];

  const value =
    (variants.includes(params.data[testName]) && params.data[testName]) ||
    (variants.includes(localStorage.getItem(key)) && localStorage.getItem(key)) ||
    pick();

  params.data[testName] = value;
  localStorage.setItem(key, value);
  if (utmSlot) params.utmParams[utmSlot] = value;

  return value;
}
```

<details>

<summary>Details</summary>

The following details cover the demo code by breaking it to smaller pieces and deep diving into the functionality.

#### 1) Add a variant field to your MP5 data schema

In your Blings project, add a data field like `abtest1`&#x20;

This is important: the variant must exist in your video data fields so you can reference it in:

* Flow Map / scene selection (branching by variant), and
* Studio content selection (conditional text/media blocks).

#### 2) Demo code: pick a variant&#x20;

Use the snippet below in your page before calling BlingsPlayer.create(...).

```javascript
// make sure to put the variable in the video data fields (in studio or in platform settings) 

function pickVariant(variants) {
  const index = Math.floor(Math.random() * variants.length);
  return variants[index];
}

// Either take from url parameters
if (!params.data.abtest1) {
  // if not in url, pick randomally
  params.data.abtest1 = pickVariant(["a", "b", "c"]); 
  // write the different options of the test, e.g "short" and "long
}
```

How it works

* If you pass `?abtest1=b` (or map it into `params.data.abtest1`), the page will respect it.
* If nothing is provided, it will randomly assign "a", "b", or "c".

This lets you support:

* deterministic assignment from marketing links / campaigns, and
* automatic “demo mode” randomization.

#### 3) Save the selected variant on UTM for analytics/BI

To make the selected version visible in analytics, copy the chosen variant into UTM parameters.

Example (simple and effective):

```js
// pick available slot, e.g
params.utmParams = {
  utm_source: params.data.abtest1,
};
```

Now, in your BI / dashboards, you can break down performance by the test variant using `utm_source` (or any UTM field you choose, like `utm_campaign`, `utm_content`, etc.).

### 4) Stickiness

Without stickiness, a user might see different versions on every refresh, which:

* breaks consistent user experience,
* makes debugging harder,
* and can pollute analytics.<br>

With localStorage stickiness:

* the first assigned variant is saved on the device/browser,
* refreshes keep showing the same version,
* and if a variant is provided later via params.data\[testName], it will overwrite and become the new sticky value.<br>

```javascript
const variants = ["a", "b", "c"];

// try existing value first, then localStorage
params.data.abtest1 =
  params.data.abtest1 ||
  localStorage.getItem("abtest1");

// validate; if missing or invalid, pick new
if (!params.data.abtest1 || !variants.includes(params.data.abtest1)) {
  params.data.abtest1 = pickVariant(variants);
}

// always persist
localStorage.setItem("abtest1", params.data.abtest1);
```

Important limitations

* localStorage is device + browser specific. A user switching devices/browsers may get a different variant.
* Clearing browser storage resets the assignment.
* If you need “same variant across devices,” store the chosen variant in your backend user profile and inject it into params.data\[testName] on load.

</details>

#### Where to use the variant inside Blings<br>

Once `params.data.abtest1` is set, you can use it in two common ways:<br>

**A) Scene selection (Flow Map)**

Route users into different scenes/paths based on the variant (a / b / c).

![](/files/jHh6KYAucZoLrGLCAaul)<br>

**B) Content selection (Studio)**

Show different copy, visuals, or offers. E.g add "text connector" and set it's data replacment based on `abtest1`

<div align="left"><figure><img src="/files/U1yQofveG6WoqLWV32pj" alt="" width="353"><figcaption></figcaption></figure></div>

#### Verification

Make sure to verify the A/B test works. Since it's "sticky" by default, meaning refresh will open the same test variant over and over, you can open a new "incognito" window every time, and see that the correct content is presented.&#x20;

Another way will be to run the following command on the console: `localStorage.clear()`&#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.blings.io/developers/getting-started/advanced-topics/a-b-test.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
