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
- Open the product in the Shopify backend for which you want to test the price.
- Create a new variant with the "Option name" "varify-pricing-test".
- Create two "Option values" for this: "Control" and "Variation".
- 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.
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
Save the experiment and give it a name
Duplicate the created variant in the newly created experiment and rename it to "New Original".
Click on "Edit" to edit the "New Original".
Open the JavaScript window and change the variable in line 4 from 'Variation' to 'Controll
Save the changes.
Set the split for the test to 50:50 between "Variation 1" and "New Control". "Original" gets 0 %.
Customize the page targeting and set it to "Contains" with your store URL.
Start the experiment.
First steps
Tracking & Evaluation
- Tracking with Varify.io
- GA4 reporting in Varify.io
- Segment and filter reports
- Audience-based evaluation in GA4
- Segment-based evaluation in GA 4
- Matomo - Results analysis
- etracker evaluation
- Calculate significance
- User-defined click events
- Evaluate custom events in explorative reports
- GA4 - Cross-Domain Tracking
- Tracking with Varify.io
- GA4 reporting in Varify.io
- Segment and filter reports
- Audience-based evaluation in GA4
- Segment-based evaluation in GA 4
- Matomo - Results analysis
- etracker evaluation
- Calculate significance
- User-defined click events
- Evaluate custom events in explorative reports
- GA4 - Cross-Domain Tracking
Web analytics integrations
Further integrations
Create experiment
Expert functions
Visual editor
- Campaign Booster: Arrow Up
- Campaign Booster: Exit Intent Layer
- Campaign Booster: Information Bar
- Campaign Booster: Notification
- Campaign Booster: USP Bar
- Add Link Target
- Browse Mode
- Custom Selector Picker
- Edit Content
- Edit Text
- Move elements
- Hide Element
- Keyword Insertion
- Redirect & Split URL Testing
- Remove Element
- Replace Image
- Responsive Device Switcher
- Style & Layout Changes
- Campaign Booster: Arrow Up
- Campaign Booster: Exit Intent Layer
- Campaign Booster: Information Bar
- Campaign Booster: Notification
- Campaign Booster: USP Bar
- Add Link Target
- Browse Mode
- Custom Selector Picker
- Edit Content
- Edit Text
- Move elements
- Hide Element
- Keyword Insertion
- Redirect & Split URL Testing
- Remove Element
- Replace Image
- Responsive Device Switcher
- Style & Layout Changes