Skip to main content

We are currently experiencing an issue that is preventing customers from submitting support tickets. Please contact us at (866) 819-4486 if you need immediate assistance.

Optimizely Knowledge Base

Test repeating page elements on your site with Optimizely Classic

  • Test elements that repeat across your site, like products on an ecommerce site or article teasers on a news site 
  • Apply changes to each element that's dynamically added to your pages, e.g. via infinite scrolling or search filters

Most modern websites have items that repeat across many different pages. These items can be products on an e-commerce site or teasers for content on a media site, for example.

These repeating elements are often important parts of your site and prime candidates for optimization. But there are a few challenges to testing them:

  • Products often appear in number of places on your site, such as search results and a product detail page
  • Experiments should run and collect results only for visitors who are actually exposed to the repeating item
  • A single page might contain multiple items of this type, so the experiment should run once for each item and only modify that particular item
  • Products are sometimes populated dynamically (for example, a visitor who scrolls to the end of a product list and new items are added or a search filter returns certain items)

Use conditional activation to target and test repeating page elements.

Let's walk through an example. Imagine you're running a test on how you display the strike price of sale items. Your hypothesis is:

By removing the strike price displayed with sale items, you remove visitors' expectations regarding cost and increase revenue with higher-priced items.

So, you create a test with two variations: an original that displays the strike price and a variation that doesn't.

Original: With Strike Price Variation: Without Strike Price

Optimizely's default activation mode executes immediately, when the page first loads. This won't work if your items populate after the initial page load, so use conditional activation instead.

Read on to create this test, step by step.

1. Insert code into Project JavaScript

First, you'll add code into Project JavaScript that runs across your site.

  1. From your Optimizely Home page, navigate to the Settings tab and select JavaScript.

  2. Paste the following sample code into the Project JavaScript field:

window.optimizelyPageModules = {
  elementsToDecorate: [],
  escapeStringForVariableName: function(string) {
    return 'elem' + string.replace(/[^a-z0-9]/g, function(s) {
      var c = s.charCodeAt(0);
      return ('000' + c.toString(16))
  waitForElement: function(selector, fn) {
    // If Mutation Observers are available
    if (window.MutationObserver || window.WebKitMutationObserver) {
      var listeners = [],
        doc = window.document,
        MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
      // Store the selector and callback to be monitored
        selector: selector,
        fn: fn

      function check() {
        // Check the DOM for elements matching a stored selector
        for (var i = 0, len = listeners.length, listener, elements; i < len; i++) {
          listener = listeners[i];
          // Query for elements matching the specified selector
          elements = optimizely.$(listener.selector);

          for (var j = 0, jLen = elements.length, element; j < jLen; j++) {
            element = elements[j];
            // Make sure the callback isn't invoked with the 
            // same element more than once
            if (!element.__optimizelyTreated) {
              element.__optimizelyTreated = true;

              var identifier = window.optimizelyPageModules.escapeStringForVariableName(listener.selector);

              // Add element to array so that it can be picked up from within variation code
              window.optimizelyPageModules.elementsToDecorate[identifier] = window.optimizelyPageModules.elementsToDecorate[
                identifier] || [];

              // Invoke the callback with the element
    , element);
      if (!observer) {
        // Watch for changes in the document
        observer = new MutationObserver(check);
        observer.observe(doc.documentElement, {
          childList: true,
          subtree: true
      // Check if the element is currently in the DOM

  itemOnPage: function(selector, callback) {
      function() {;
    // Tracking script usage
    window.optimizely = window.optimizely || [];
      'type': 'integration',
      'OAuthClientId': '6312952247'
  getElementForTreatment: function(selector, fn) {

    var identifier = window.optimizelyPageModules.escapeStringForVariableName(selector);
    if (typeof window.optimizelyPageModules.elementsToDecorate[identifier] !== "undefined" && window.optimizelyPageModules
      .elementsToDecorate[identifier].length > 0) {, window.optimizelyPageModules.elementsToDecorate[identifier].pop());
    } else {
      return false;

2. Find the jQuery selector

Next, find the jQuery selector that captures all the elements you want target and none that you don't. Open the developer console and click the element to see the selector.

In the example, you want to test all elements with the class product that contains a strike price. The image is indicated by this class: product-price-discount.

A valid jQuery selector that matches these elements:


3. Create an experiment

Then, use the six steps to create an experiment.

To make sure your experiment runs everywhere the elements appear, use URL Targeting to target the entire site. Use substring match to target your domain name.


4. Set conditional activation

To make sure the experiment triggers for each element with a strike price, set conditional activation. 

  1. Navigate to Options, then Activation Mode.

  2. Switch to Conditional Activation:

  3. Insert the following template:

function(activate, options) {
  optimizelyPageModules.itemOnPage(".product:has(.product-price-discount)", activate);

Note that the example above uses selector to identify every element with the product that contains product-price-discount, which we identified above.

Replace this part of the code with your own selector.


5. Create variation JavaScript to modify elements

  1. Then, open the <edit code> box.

  2. Add the following Javascript template:

/* _optimizely_evaluate=editor_only */
optimizelyPageModules.itemOnPage('.product:has(.product-price-discount)', function(){}); 
/* _optimizely_evaluate=end_editor_only */ 
/* _optimizely_evaluate=force */
optimizelyPageModules.getElementForTreatment('.product:has(.product-price-discount)', function(elem){
  var price = $(elem).find('.product-price-discount i').text();
    .replaceWith('<span class="product-price">' + price + '</span>');

Here's what this code does, step by step:

  • The first three lines run in the Visual Editor only. This activates the experiment there and enables you to immediately preview the changes you made in the Editor. This code has no effect on your visitor's experience – removing it would only result in the Visual Editor not showing the changes.

    Use it to make sure that you use the same selector that you set in the conditional activation code.

  • The fourth line tells Optimizely that this code should run as early as possible. By using conditional activation, we make sure that the elements we're modifying are on the page.

  • The getElementForTreatment method returns the element that the experiment has activated for and allows Optimizely to make modifications to it.

  • The experiment will activate for each element that needs to be modified (so, three times if a page contains three products with strike price on the page), so we need to make sure to only modify this particular element by using the reference to elem.

6 Verify and publish

Save the experiment. QA and navigate around your site again.

If you're bucketed in the variation, we should now see the sale items without strike price!