• Shopify - Test prices with Varify.io

    Table of contents

    In short

    To find out at which price your products achieve the best contribution margin, you can carry out price tests. An additional variant filter is added for the corresponding product to be tested. You use this filter to set the alternative price.

    The experiment is invisible to the user, as the price filter is not visible to the user. A JavaScript code in the A/B test then ensures that either the original price or the price to be tested is displayed on the product detail page (PDP), depending on the variant. 

    To ensure that the new price is also displayed on the category pages (collection pages) and the price filter is not visible, enter the URLs of the products to be tested in the JavaScript code provided.

    Why test Shopify prices?

    Pricing tests on Shopify help you to find out which price works best for a product - i.e. which price leads to more sales or higher turnover. Targeted A/B tests allow you to test different price variants simultaneously without disrupting the shopping experience. This allows you to make data-based decisions and optimize your store for greater success.

    Step 1: Create filters and adjust prices

    1. Open the product in the Shopify backend for which you want to test the price.
    2. Create a new variant with the "Option name" "varify-pricing-test".
    3. Create two "Option values" for this: "Control" and "Variation".

    1. If the product has other variants, such as a color filter, drag and drop the variant filter to the top so that it is positioned above the other filters. This is important for the test to work correctly.

    1. Set the new price to be tested for each product variant in the "varify-pricing-test" price variant.

      • Tip: Activate "Group by varify-pricing-test" to better manage the variants.

      • If you have different variants or colors, you should also adjust the variant price here

      • Also remember to adjust the available quantity so that the product is available in the store.
        For example, if you have 1,000 units of the product in stock, you can set 500 units for the original price and 500 units for the new variant price.

    Step 2: Identify the relevant CSS selectors

    Now find the CSS selectors for the elements: 

    • Price filter
    • Product card on the Collection page
    • Price on the Collection page.

    Price filter

    • Open a product detail page (PDP) on which you have set up the price filter and the experiment is to be carried out

    • Open the developer tools (F12 or right-click > "Inspect").

    • Use the inspection tool to select the newly created varify-pricing-test filter element so that it is completely highlighted - this will ensure that you have identified the correct selector.

      • In this example, the first <div>-element in the <variant-selects>-element is selected. Depending on the template, the structure and HTML tags and classes may have different names.

    • Right-click at the highlighted position in the code and then select : Copy → Copy selector
      This copies the exact CSS selector for the price filter.

    • It is best to save the copied selector in a document or a note - you will need it again soon.

    Product card on the Collection page

    • Open a collection page.

    • Examine the page (F12 or right-click > "Examine") and select a product card element.

    • Find the parent element of the card - usually the outer element of the product card is a list element.

      • Copy the class again using "Copy selector" and save it in the same document in which you saved the selector for the price filter

    Price on the Collection page

    • Open the product tile in the collection page again in the developer tools.

    • Go deeper into the structure of the map and search for the "Price" element

    • Make sure that you really select the element that is to change during the test - i.e. the specific text or HTML block that shows the price.

    • In this case, the class of the price element price__regular. It may be different for your side.

    • Copy this class name using "Copy selector" and save it with the other two class names determined so far

    Step 3: Customize code for the experiment

    Create a new experiment via the Varify Dashboard. To do this, enter the store start page in the input field and click on "Create new Experiment". Below you will find the JavaScript code for the price test. Add this to the variant of your experiment using the "Add JS" function. 

    To ensure that the price test also works technically in your store, a few adjustments need to be made to the JavaScript code provided. Change the JavaScript in your variant as follows:

    Line 1: Paste the copied CSS selector for the price filter into the quotation marks.

    Line 2: Enter the class of the price - i.e. the element that is to change later.

    Line 3: Specify the class of the product tile so that the code knows where the price is on the collection page.

    From line 7: Add here all product URLs on which the price test is to be carried out. (If you are performing a price test for only one product, you only need to add one URL here and you can delete the other URLs). Make sure that you keep the corresponding format of the URLs ('URL'). Add a comma after each 'URL' if more URLs follow.

    💡 Note: The price on the collection pages is completely replaced by the code. If additional currency symbols or words such as "ab" are attached to the price, you can adjust these directly in the code (line 81)

    Without additional text:
    e.g. new price -> 25,99

    				
    					priceElement.textContent = `${newPrice}`;
    				
    			

    With additional text:
    e.g. new price -> From 25,99 EUR

    				
    					priceElement.textContent = `From ${newPrice} EUR`;
    				
    			

    JavaScript code for the price test

    				
    					const varifyPriceFilterSelector = '#variant-selects-template--25418368778580__main > div:nth-child(1)';
    const priceClass = 'price__regular';
    const cardClass = 'grid__item';
    const desiredVariantOption = 'Variation'; // Variation or Control
    
    // Only URLs – variant IDs no longer required
    const productURLs = [
        'https://demo-shop.com/products/article1',
        'https://demo-shop.com/products/article2',
        'https://demo-shop.com/products/article3'
    ];
    
    const updatedHandles = new Set();
    
    function hidePriceFilterOnMatchingProductPages() {
        const currentURL = window.location.href;
        const matchesProductPage = productURLs.some(url => currentURL.includes(url));
    
        if (matchesProductPage && varifyPriceFilterSelector) {
            const style = document.createElement('style');
            style.textContent = `
          ${varifyPriceFilterSelector} {
            display: none !important;
          }
        `;
            document.head.appendChild(style);
            console.log('Hiding price filter on matching product page:', varifyPriceFilterSelector);
        }
    }
    
    hidePriceFilterOnMatchingProductPages();
    
    function formatPrice(priceInCents) {
        return (priceInCents / 100).toFixed(2);
    }
    
    function extractHandleFromHref(href) {
        const match = href.match(/\/products\/([^/?#]+)/);
        return match ? match[1] : null;
    }
    
    function extractHandlesFromURLs(urls) {
        return urls.map(extractHandleFromHref).filter(Boolean);
    }
    
    function updateProducts(retryCount = 0) {
        const productCards = document.querySelectorAll(`.${cardClass}`);
        const allowedHandles = extractHandlesFromURLs(productURLs);
    
        if (productCards.length === 0 && retryCount < 5) {
            console.warn(`No product cards found – retrying (${retryCount + 1}/5)`);
            setTimeout(() => updateProducts(retryCount + 1), 300);
            return;
        }
    
        allowedHandles.forEach((handle) => {
            if (updatedHandles.has(handle)) return;
    
            fetch(`/products/${handle}.js`)
                .then(response => response.json())
                .then(product => {
                    const targetVariant = product.variants.find(v => v.option1 === desiredVariantOption);
                    if (!targetVariant) {
                        console.warn(`No variant found with option1 === '${desiredVariantOption}' for "${handle}"`);
                        return;
                    }
    
                    let updated = false;
    
                    productCards.forEach(card => {
                        const link = card.querySelector('a[href*="/products/"]');
                        if (!link) return;
    
                        const href = link.getAttribute('href');
                        const linkHandle = extractHandleFromHref(href);
    
                        if (linkHandle === handle) {
                            const priceElement = card.querySelector(`.${priceClass}`);
                            if (priceElement) {
                                const oldPrice = priceElement.textContent.trim();
                                const newPrice = formatPrice(targetVariant.price);
                                priceElement.textContent = `${newPrice}`;
    
                                console.log(`"${product.title}" – Price updated: ${oldPrice} → €${newPrice}`);
                            }
    
                            const imageElement = card.querySelector('.product-card-image img');
                            if (imageElement && targetVariant.featured_image) {
                                imageElement.src = targetVariant.featured_image.src;
                                console.log(`Image updated for "${product.title}".`);
                            }
    
                            // Update link with ?variant=...
                            const url = new URL(link.href, window.location.origin);
                            url.searchParams.set('variant', targetVariant.id);
                            link.href = url.toString();
    
                            updated = true;
                        }
                    });
    
                    if (updated) {
                        updatedHandles.add(handle);
                    }
                })
                .catch(error => {
                    console.error(`Error loading product "${handle}":`, error);
                });
        });
    }
    
    // Optional: Set filter selection on the PDP
    function setPriceFilter() {
        const selectElement = document.querySelector(`${varifyPriceFilterSelector} select`);
        if (selectElement) {
            selectElement.value = desiredVariantOption;
            selectElement.dispatchEvent(new Event('input', { bubbles: true }));
            selectElement.dispatchEvent(new Event('change', { bubbles: true }));
        }
    }
    
    // Initial call after DOM ready
    window.varify.helpers.onDomLoaded(() => {
        setPriceFilter();
        updateProducts();
    });
    
    // Optional: Repeat on DOM changes
    window.varify.helpers.onDomChanged(() => {
        updateProducts();
    });
    				
    			

    Step 4: Save the new experiment

    1. Save the experiment and give it a name

    2. Duplicate the created variant in the newly created experiment and rename it to "New Original".

    3. Click on "Edit" to edit the "New Original".

    4. Open the JavaScript window and change the variable in line 4 from 'Variation' to 'Controll

    5. Save the changes.

    6. Set the split for the test to 50:50 between "Variation 1" and "New Control". "Original" gets 0 %.

    7. Customize the page targeting and set it to "Contains" with your store URL.

    8. Start the experiment.

  • First steps