---
title: JavaScript SDK v6+ quickstart
slug: feature-experimentation/docs/javascript-sdk-v6-quickstart
docTags: 
createdAt: 2026-08-05T20:40:01.000Z
---

## Part 1: Create a sample app

### 1. Get a free account

You need an Optimizely account to follow this guide. If you do not have an account, you can [register for a free account](https://www.optimizely.com/free-feature-flagging/). If you already have an account, navigate to your Feature Experimentation project.

### 2. Get your SDK key

To find your SDK Key in your Optimizely project:

1. Go to **Settings** > **Primary Environment**.
2. Copy and save the **SDK Key** for your primary environment.

:::hint{type="warning"}
**Important**
Each environment has its own SDK key. Ensure you copy the correct key.
:::

![SDK key for primary environment](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/TEbXdmYlSZ9qVcA3GiXVm-20260723-144350.png "sdk_key.png")

### 3. Copy the sample code

To try out the JavaScript SDK:

1. Install Optimizely. You have the following options:
   - (Recommended) **Run locally** – If you want to run using Node (best practice in production), then use the following **using NPM** and **using Yarn** code examples.
   - **Run without installing** – If you want to run in a demo environment, for example CodePen, without installing the SDK locally, use the **using HTML script tags** code example.

:::hint{type="danger"}
**Warning**
**DO NOT** use the unpkg CDN and the **using HTML script tags** example in production environments.

If you rely on unpkg URLs without specifying the package version, your application may unexpectedly break when a new major version of the JavaScript SDK is published to npm, even if you did not explicitly upgrade.

[unpkg](https://www.unpkg.com) is a public CDN for open-source packages published to npm. It

- has no uptime guarantees.
- automatically serves the latest version of an npm package when no version is specified in the url, including breaking major version changes.

If you still decide to use unpkg in production, ensure that the version of the SDK is specified in the URL.
:::

```shell
# From an empty project directory, create an `optydemo.js` file. Run the following terminal command to install Optimizely Feature Experimentation.
# 
# Replace VERSION_NUMBER with the Optimizely JavaScript SDK version you used to test.
# For example: npm install --save @optimizely/optimizely-sdk@6.0.0
npm install --save @optimizely/optimizely-sdk@VERSION_NUMBER
```

```shell
# From your project directory run the following terminal command to install Optimizely Feature Experimentation: 
# 
# Replace VERSION_NUMBER with the Optimizely JavaScript SDK version you used to test.
# For example: yarn add @optimizely/optimizely-sdk@6.0.0
yarn add @optimizely/optimizely-sdk@VERSION_NUMBER
```

```html
<html>
  <head>
   <!-- 
    ---  Do not use unpkg in production environments. 
    ---  Replace VERSION_NUMBER with the Optimizely JavaScript SDK version you used to test.
    ---  For example: https://unpkg.com/@optimizely/optimizely-sdk@6.0.0/dist/optimizely.browser.umd.min.js"  
    -->
    <script src="https://unpkg.com/@optimizely/optimizely-sdk@VERSION_NUMBER/dist/optimizely.browser.umd.min.js"></script>
  </head>
  <body>
  </body>
</html>
```

2. Create a blank project in CodePen or create a blank file called `optimizely-js-quickstart.html` locally.
3. Copy the following code sample into the file you created in the previous step.
4. Replace `YOUR_SDK_KEY` with the SDK key you found in a previous step. Replace `VERSION_NUMBER` with the JavaScript SDK version you want to target.

```javascript
<!DOCTYPE html>
<html>

<head>
  <title>Quickstart Guide</title>
  <script src="https://unpkg.com/@optimizely/optimizely-sdk@VERSION_NUMBER/dist/optimizely.browser.umd.min.js"></script>
</head>

<body>
  <pre>Welcome to our Quickstart Guide!</pre>
  <pre id="errors"></pre>
  <pre id="experiences"></pre>
  <pre id="result"></pre>
  <script>
    // instantiate an Optimizely client from the datafile
    const {
      createPollingProjectConfigManager,
      createBatchEventProcessor,
      createOdpManager,
    } = window.optimizelySdk;

    const SDK_KEY="YOUR_SDK_KEY";

    const pollingConfigManager = createPollingProjectConfigManager({
      sdkKey: SDK_KEY
    });

    const batchEventProcessor = createBatchEventProcessor();
    const odpManager = createOdpManager();

    const optimizely  = window.optimizelySdk.createInstance({
      projectConfigManager: pollingConfigManager,
      eventProcessor: batchEventProcessor,
      odpManager: odpManager,
    });

    optimizely.onReady().then(() => {
      const errors = document.getElementById('errors');
      const experiences = document.getElementById('experiences');
      let hasOnFlags = false;
      
      for (let i = 0; i < 10; i++) {
        // to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
        const userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();

        // Create hardcoded user & bucket user into a flag variation
        const user = optimizely.createUserContext(userId);

        // "product_sort" corresponds to a flag key in your Optimizely project
        const decision = user.decide('product_sort');
        const variationKey = decision.variationKey;

        // did decision fail with a critical error?
        if (variationKey === null) {
          errors.innerText += `\n\ndecision error: ${decision['reasons']}`;
        }
        
        // get a dynamic configuration variable
        // "sort_method" corresponds to a variable key in your Optimizely project
        const sortMethod = decision.variables['sort_method'];

        if (decision.enabled) {
          hasOnFlags = true;
        }

        // Mock what the user sees with print statements (in production, use flag variables to implement feature configuration)
        // always returns false until you enable a flag rule in your Optimizely project
        experiences.innerText += `\n\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey}`
          + ` and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`;
      }

      var result = document.getElementById('result');
      if (!hasOnFlags) {
        result.innerText += '\n\nFlag was off for everyone. Some reasons could include' +
          '\n1. Your sample size of users was too small. Rerun, or increase the iterations in the FOR loop' +
          '\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used' +
          ' the right key for the environment where your flag is toggled to ON.' +
          '\nCheck your key at https://app.optimizely.com/v2/projects/<your-project-id>/settings/implementation';
      }
    }).catch((err) =>{
    	console.error("onReady error:", err);
    });
  </script>
</body>

</html>
```

```javascript
import {
  createBatchEventProcessor,
  createInstance,
  createOdpManager,
  createPollingProjectConfigManager,
} from "@optimizely/optimizely-sdk";

const SDK_KEY="YOUR_SDK_KEY";

const pollingConfigManager = createPollingProjectConfigManager({
  sdkKey: SDK_KEY
});

const batchEventProcessor = createBatchEventProcessor();
const odpManager = createOdpManager();

const optimizely = createInstance({
  projectConfigManager: pollingConfigManager,
  eventProcessor: batchEventProcessor,
  odpManager: odpManager,
});

optimizely.onReady().then(() => {
  let hasOnFlags = false;
  
  for (let i = 0; i < 10; i++) {
    // to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
    const userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();

    // Create hardcoded user & bucket user into a flag variation
    const user = optimizely.createUserContext(userId);

    // "product_sort" corresponds to a flag key in your Optimizely project
    const decision = user.decide('product_sort');
    const variationKey = decision.variationKey;

    // did decision fail with a critical error?
    if (variationKey === null) {
      console.log('decision error: ', decision['reasons']);
    }
    
		// get a dynamic configuration variable
    // "sort_method" corresponds to a variable key in your Optimizely project
    const sortMethod = decision.variables['sort_method'];

    if (decision.enabled) {
      hasOnFlags = true;
    }

    // Mock what the user sees with print statements (in production, use flag variables to implement feature configuration)
    // always returns false until you enable a flag rule in your Optimizely project
    console.log(`\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey}`
      + ` and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`);
  }

  if (!hasOnFlags) {
    console.log('\n\nFlag was off for everyone. Some reasons could include' +
      '\n1. Your sample size of users was too small. Rerun, or increase the iterations in the FOR loop' +
      '\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used' +
      ' the right key for the environment where your flag is toggled to ON.' +
      '\nCheck your key at https://app.optimizely.com/v2/projects/<your-project-id>/settings/implementation');
  }
}).catch((err) =>{
   console.error("onReady error:", err);
});
```

:::hint{type="warning"}
**Important**
Do not run your app yet, because you still need to configure the flag in the Optimizely app.
:::

## Part 2: Run your app

After completing [Part 1](docId\:FcM5PaCjwrFb_kRI0qpua), your app does nothing. You need to create a flag and a flag rule in the Optimizely app to enable the app.

### 1. Create the feature flag

A [flag](docId\:CFAu9P5PdLLMB8GsFn_fo) lets you control the users that are exposed to new code in your application. For this quickstart, imagine that you are rolling out a redesigned sorting feature for displaying products.

Create a flag in your Feature Experimentation project named **product\_sort** and give it a variable named **sort\_method**.

1. From the **Flags** tab, click **Create New Flag** .
2. Enter *product\_sort* in the **Name** field.
3. Keep the auto-created **Key**, *product\_sort*, and click **Create Flag**. The **Key** corresponds to the flag key in your sample app.

Next, create a variable in your flag.

1. In your new flag, `product_sort`, click **Variables** and click **Add Variable**.
2. Select **String** from the **Add Variable** drop-down list.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/2wZT5DIuI5mBUbnLYSzqt_b64280152e031dfcfefa7b96befa123d78d41eaa4c1f62ba661368d3452d8578-image.png)

3. Enter *sort\_method* for the **Variable Key**, which corresponds to the variable key in your sample app.
4. Enter *alphabetical* for the **Default Value**, which represents your old sorting method. The new sorting method is what you are rolling out.
5. Click **Save**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/bol_jOhC7rhyzq3z5_lQY_b19690d-string-variable-javascript.png)

Next, create a variation in your flag:

1. Click **Variations** and select the **On** variation. A variation is a wrapper for a collection of variable values.
2. For the **sort\_method** variable value, enter *popular\_first*, which represents your new sorting method.
3. Click **Save**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/Jw49kI1hBAvmVSgxE1mny_2c6a215-on-variation-popular-first.png)

### 2. Create the flag delivery rule

Your sample app *still* does nothing because you need to create and enable a [flag rule](docId\:CFAu9P5PdLLMB8GsFn_fo).

Make a [targeted delivery rule](docId\:R0KSPrSRYev0Q6jXL27QK) for the **On** variation for the **product\_sort** flag. A targeted delivery lets you gradually release a feature flag to users but with the flexibility to roll it back if you encounter bugs.

1. Ensure you are in your primary environment (because you are using the primary environment SDK key from [Part 1](docId\:FcM5PaCjwrFb_kRI0qpua)).

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/RtAsh_IifAIFq35w6NSsR_0a5d0f9-image.png)

2. Click **Add Rule** and select **Targeted Delivery**.
3. Enter *Targeted Delivery* for the **Name** field.
4. Keep the default **Key** and **Audiences**.
5. Set the **Traffic Allocation** slider to 50%. This delivers the **product\_sort** flag to 50% of everyone who triggers the flag in this environment. You can roll out or roll back the **product\_sort** flag to a percentage of traffic whenever you want.
6. From the **Deliver** drop-down list, select the **On** variation.
7. Click **Save**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/Amt-ksRr-q3urU8UtQsIk_0878a69-image.png)

### 3. Run your sample app

To run your sample application:

1. Click **Run** on your targeted delivery rule:

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/XmGdpCrD9PUacZfMisVdO_de01aa0-image.png)

2. Click **Ok** on the **Ready to Run Status** page. This lets you know that your ruleset has not been set to run, yet.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/_aDAwcuNhUJG50GImI1Aa_7b4d47d-image.png)

3. Click **Run** on your ruleset (flag):

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/_BNsfhXQqfgvuAAZFi609_d2c103d-image.png)

If you use CodePen to create the experiment, you should already see the output. Otherwise, open `optimizely-js-quickstart.html` file you created earlier using the browser menu (**File** > **Open File...**). Output displays similar to the following:

```powershell
Flag on. User number 6998 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 1177 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 9714 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 4140 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 4994 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag off. User number 8700 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913

Flag off. User number 9912 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913

Flag on. User number 6560 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 9252 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 6582 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
```

:::hint{type="info"}
**Note**
You will not get exactly 50% of your user traffic in the "on" variation, because you are working with such small numbers of users. Also, the users who got an "off" flag did not make it into the 50% traffic you set, so they fell through to the default "Off" rule (*default-rollout* in the preceding print statements).
:::

### 4. How it works

So far, you:

- Created a flag, flag variable, and a flag variation (wrapper for your variables) in the Optimizely app.
- Implemented a flag in your app with the **Decide** method.

What is going on in your sample app?

### How it works: decide to show a user a flag

The SDK’s [Decide](docId\:aD2SIJpA4SEjMECie93Tn) method determines whether to show or hide the feature flag for a specific user.

:::hint{type="info"}
**Note**
You can reuse this method for different flag rules, whether for delivering to more traffic, or running an experiment to show different sorting methods to just a portion of users.
:::

After you learn which sorting method works best to increase sales, roll out the product sort flag to all traffic with the method set to the optimum value.

In your sample app:

```javascript
const user = optimizely.createUserContext(userId);
// "product_sort" corresponds to the flag key you create in the Optimizely app
const decision = user.decide('product_sort');
```

:::hint{type="info"}
**Note**
Optionally include attributes when you create your user (not shown in your sample app), so that you can target specific audiences. For example:

```javascript
const attributes = { logged_in: true };
const user = optimizely.createUserContext('user123', attributes);
```
:::

### How it works: configure flag variations

You can dynamically configure a flag variation using flag variables. In your sample app:

```javascript
// always returns false until you enable a flag rule in the Optimizely app
if (decision.enabled) 
{
  // "sort_method" corresponds to variable key you define in Optimizely app
 const sortMethod = decision.variables['sort_method'];
 console.log('sort_method: ', sortMethod);
}
```

For your **product\_sort** flag, you can configure variations with different **sort\_method** values, sorting by popular products, relevant products, promoted products, and so on. You can set different values for the sort method at any time in the Optimizely app.

## Part 3: Run an A/B test

[Part 2](docId\:FcM5PaCjwrFb_kRI0qpua) of this tutorial guided you through a targeted delivery because it is the most straightforward flag rule. However, you often want to [A/B test](docId\:raDQAUQpQJywODzUkXKhZ) how users react to feature flag variations *before* you roll out a flag delivery.

- [Targeted delivery rule](docId\:R0KSPrSRYev0Q6jXL27QK) – You can roll out your flag to a percentage of your general user base (or to specific audiences), or roll back if you encounter bugs.
- [A/B test rule](docId\:raDQAUQpQJywODzUkXKhZ) – Experiment by A/B testing a flag before you invest in delivering so you know what to build. Track how users behave in flag variations, then interpret your experiment results using the Optimizely Stats Engine.

For Part 3, you will run an A/B test on the **On** variation of your **product\_sort** flag.

### 1. Add event tracking

You need to add a [Track Event method](docId:7z1ZuPEvPJJkghG28HRv9) to your sample app, so you can mock up user events and then see [metrics](docId:06YPvA1xY9tK6261dIE66).

1. Delete your old sample code, and paste the following code.
2. **Replace your SDK key**. See [Get your SDK Key](docId\:FcM5PaCjwrFb_kRI0qpua).
3. Do not run your app yet because you still need to configure the A/B test in the Optimizely application.

```javascript
<!DOCTYPE html>
<html>

<head>
  <title>Quickstart Guide</title>
  <script src="https://unpkg.com/@optimizely/optimizely-sdk@VERSION_NUMBER/dist/optimizely.browser.umd.min.js"></script>
</head>

<body>
  <pre>Welcome to our Quickstart Guide!</pre>
  <pre id="errors"></pre>
  <pre id="experiences"></pre>
  <pre id="result"></pre>
  <script>
     const {
      createPollingProjectConfigManager,
      createBatchEventProcessor,
      createOdpManager,
    } = window.optimizelySdk;

    const SDK_KEY="YOUR_SDK_KEY";

    const pollingConfigManager = createPollingProjectConfigManager({
      sdkKey: SDK_KEY
    });

    const batchEventProcessor = createBatchEventProcessor();
    const odpManager = createOdpManager();

    const optimizely  = window.optimizelySdk.createInstance({
      projectConfigManager: pollingConfigManager,
      eventProcessor: batchEventProcessor,
      odpManager: odpManager,
    });


    optimizely.onReady().then(() => {
      const experiences = document.getElementById('experiences');

      // mock tracking a user event so you can see some experiment reports
      const mockPurchase = (user) => {
        const question = '\nPretend that user ' + user.getUserId() + ' made a purchase? y/n';
        const answer = prompt(question);
        
        // track a user event you defined in the Optimizely app
        if (answer == 'y') {
          user.trackEvent('purchase');
          experiences.innerText += `\nOptimizely recorded a purchase in experiment results for user ${user.getUserId()}`;
        }
        else {
          experiences.innerText += `\nOptimizely didn't record a purchase in experiment results for user ${user.getUserId()}`;
        }
      }

      const runExperiment = async () => {
        let hasOnFlags = false;
        for (let i = 0; i < 10; i++) {
          // to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
          let userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();

          // Create hardcoded user & bucket user into a flag variation
          let user = optimizely.createUserContext(userId);

          // 'product_sort' corresponds to a flag key in your Optimizely project
          let decision = user.decide('product_sort');
          let variationKey = decision.variationKey;

          // did decision fail with a critical error?
          if (variationKey === null) {
            errors.innerText += `\n\ndecision error: ${decision['reasons']}`;
          }
          // get a dynamic configuration variable
          // 'sort_method' corresponds to a variable key in your Optimizely project
          let sortMethod = decision.variables['sort_method'];
          if (decision.enabled) {
            hasOnFlags = true;
          }

          // Mock what the user sees with print statements (in production, use flag variables to implement feature configuration)
          // always returns false until you enable a flag rule in your Optimizely project
          experiences.innerText += `\n\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey}`
            + ` and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`;

          mockPurchase(user);
        }

        const result = document.getElementById('result');
        if (!hasOnFlags) {
          result.innerText += '\n\nFlag was off for everyone. Some reasons could include' +
            '\n1. Your sample size of users was too small. Rerun, or increase the iterations in the FOR loop' +
            '\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used' +
            ' the right key for the environment where your flag is toggled to ON.' +
            '\nCheck your key at https://app.optimizely.com/v2/projects/<your-project-id>/settings/implementation';
        } else {
          result.innerText += '\n\nDone with your mocked A/B test. ' +
            `\nCheck out your report at https://app.optimizely.com/v2/projects/<your-project-id>/reports` +
            '\nBe sure to select the environment that corresponds to your SDK key';
        }
      }

      runExperiment();
    }).catch((err) => {
    	console.error("onReady error:", err);
    });
  </script>
</body>

</html>
```

```javascript
import {
  createBatchEventProcessor,
  createInstance,
  createOdpManager,
  createPollingProjectConfigManager,
} from "@optimizely/optimizely-sdk";

const SDK_KEY="YOUR_SDK_KEY";

const pollingConfigManager = createPollingProjectConfigManager({
  sdkKey: SDK_KEY
});

const batchEventProcessor = createBatchEventProcessor();
const odpManager = createOdpManager();

const optimizely = createInstance({
  projectConfigManager: pollingConfigManager,
  eventProcessor: batchEventProcessor,
  odpManager: odpManager,
});

// mock tracking a user event so you can see some experiment reports
const mockPurchase = (user) => {
  const question = '\nPretend that user ' + user.getUserId() + ' made a purchase? y/n';
  const answer = prompt(question);
  
  // track a user event you defined in the Optimizely app
  if (answer == 'y') {
    user.trackEvent('purchase');
    console.log(`\nOptimizely recorded a purchase in experiment results for user ${user.getUserId()}`);
  }
  else {
    console.log(`\nOptimizely didn't record a purchase in experiment results for user ${user.getUserId()}`);
  }
}

const runExperiment = async () => {
  let hasOnFlags = false;
  for (let i = 0; i < 10; i++) {
    // to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
    let userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();

    // Create hardcoded user & bucket user into a flag variation
    let user = optimizely.createUserContext(userId);

    // 'product_sort' corresponds to a flag key in your Optimizely project
    let decision = user.decide('product_sort');
    let variationKey = decision.variationKey;

    // did decision fail with a critical error?
    if (variationKey === null) {
      console.log(' decision error: ', decision['reasons']);
    }
    // get a dynamic configuration variable
    // 'sort_method' corresponds to a variable key in your Optimizely project
    let sortMethod = decision.variables['sort_method'];
    if (decision.enabled) {
      hasOnFlags = true;
    }

    // Mock what the user sees with print statements (in production, use flag variables to implement feature configuration)
    // always returns false until you enable a flag rule in your Optimizely project
    console.log(`\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey}`
      + ` and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`);

    await mockPurchase(user);
  }

  if (!hasOnFlags) {
    console.log('\n\nFlag was off for everyone. Some reasons could include' +
      '\n1. Your sample size of users was too small. Rerun, or increase the iterations in the FOR loop' +
      '\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used' +
      ' the right key for the environment where your flag is toggled to ON.' +
      '\nCheck your key at https://app.optimizely.com/v2/projects/<your-project-id>/settings/implementation');
  } else {
    console.log('\n\nDone with your mocked A/B test. ' +
      `\nCheck out your report at https://app.optimizely.com/v2/projects/<your-project-id>/reports` +
      '\nBe sure to select the environment that corresponds to your SDK key');
  }
}

optimizely.onReady().then(() => {
  runExperiment();
}).catch((err) =>{
	console.error("onReady error:", err);
});
```

### 2. Delete other rules in free accounts

If you have a free Optimizely account, you must delete the Targeted Delivery you created in [Part 2](docId\:FcM5PaCjwrFb_kRI0qpua) before you create your A/B test:

1. Select the **Flag** that contains the Targeted Delivery you created in Part 2 from the Flags tab.
2. Select the primary environment and the Targeted Delivery rule you created in Part 2.
3. Click **More Options** > **Delete**:

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/7Bzb69sbZSZFHT9NTQ4ED_9c4d711-image.png)

4. Click **Save**.

### 3. Create the A/B test

To create an A/B Test rule in your Feature Experimentation project, in the flag you created in [Part 2](docId\:FcM5PaCjwrFb_kRI0qpua):

1. Click **Add Rule** and select **A/B Test**.
2. Enter *Experiment* for the **Name** field.
3. Keep the default **Key** and **Audiences**.
4. Keep the **Ramp Percentage** traffic allocation slider set to 100%.

### 4. Add an event

In an experiment, you track users' relevant actions to measure how they react to your flag variations. To define the actions you want to track, called [events](docId\:SViQcZpYCosJLYzXIiAhP):

1. Click on the **Metrics** field.
2. Click **Create new event**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/ABtmFjVvhSrqNwPs7CHLn_b3754e5-create-new-event.png)

3. Enter *purchase* for the **Event Name**, and the **Event Key** is automatically filled.
4. (Optional) Enter a **Description**. You want to know whether the new sorting flag helps customers figure out what to buy, so track whether the user makes a purchase after they are shown the products in a new order.
5. Click **Create Event**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/9LE8WDmOy2Q5kZVrFadV3_7ff42d7-javascript-create-event.png)

6. In the **Add Metric** modal, leave the defaults, measure **increase** in **unique conversions**.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/36JKuOqd-aLiHHzzfZMng_357aa0f-add-metric-javascript.png)

7. Click **Add Metric**.
8. Leave the default **Off** variation as a control. Select the **On** variation you configured in [Part 2](docId\:FcM5PaCjwrFb_kRI0qpua):

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/CNv7VonmAHhMtwD0xieeR_92c5706-on-variation.png)

:::hint{type="info"}
**Note**
You are not limited to two variations; you can also create A/B tests with multiple variations.
:::

9. Click **Save** to create your A/B Test rule.
10. Click **Run** on the A/B test rule.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/fDdLaCLlJP_hoKLjtNI54_9ae34f5-image.png)

### 5. Run the A/B test

Ensure your ruleset's (flag's) status is **Running**, and the rule's status is **Running** so your experiment can run:

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/PlkFsMB2R-JpWpSpqy3Hj_cce40a5-image.png)

Using your browser, open the html file using the browser menu (**File** > **Open File...**). The output should display similar to the following:

```powershell
Flag on. User number 1496 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment_1
Pretend that user 1496 made a purchase? y/n
n
Optimizely didn't record a purchase in experiment results for user 1496


Flag off. User number 1194 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user 1194 made a purchase? y/n
y
Optimizely recorded a purchase in experiment results for user 1194


Flag off. User number 5815 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user 5815 made a purchase? y/n
y
Optimizely recorded a purchase in experiment results for user 5815


Flag on. User number 1248 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment_1
Pretend that user 1248 made a purchase? y/n
y
Optimizely recorded a purchase in experiment results for user 1248


Flag off. User number 9580 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user 9580 made a purchase? y/n
n
Optimizely didn't record a purchase in experiment results for user 9580


Done with your mocked A/B test.
Check out your report at https://app.optimizely.com/v2/projects/<your-project-id>/reports
Be sure to select the environment that corresponds to your SDK key
```

### 6. See your A/B test results

Go to the [Reports](docId:_K6n7h_MZ8b0xn6yWPrrq) tab and select your experiment to see your results.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/NwBQPuQf1p8tP1rQx7ApQ_a2128ff-experiment-results-page.png)

Your results should look similar to the following:

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/_edT0H-8axHbxYPF9tCzq_9897f20-actual-experiment-results-page.png)

:::hint{type="info"}
- **Note**
  You might not see the exact user traffic percentages you configured for your flag variations until you have larger numbers of users.
- You might not see your user traffic immediately. Refresh the browser to refresh traffic.
- Your experiment results will not tell you a winning variation until you have a large number of users (on the order of 100,000).
:::

### 7. How it works

For an A/B test, you need a way to tell Optimizely when a user makes a purchase in your app and map this event in your app code to the specific event you created in Optimizely. Luckily the SDK has a method for that! Use the [Track Event](docId\:mQXjbiVc5hcZH-oUk1knC) method and pass in the key for the event you created (`purchase`). In your sample app:

```javascript
// Track how users behave when they see a flag variation
// for example, after your app processed a purchase, let Optimizely know what happened:
user.trackEvent('purchase');
```

:::hint{type="info"}
**Note**
Optionally add tags to your event to enrich it (not shown in your sample app). You can also use reserve tag keys like **revenue** to track quantitative results. For example:

```javascript
const tags = {
  category: 'shoes',
  revenue: 6432,
};

user.trackEvent('purchase', tags);
```
:::

## Conclusion

Congratulations! You configured and launched your first Feature Experimentation experiment. While this example focused on optimizing sales, Optimizely’s experimentation platform can support an open-ended set of experimentation use cases.

See the entire [JavaScript](docId\:BH1d17PyLwDzM5yw6kvo-) documentation to learn more ways to optimize your software using experimentation.
