Google Ads feeds can contain more than one price for an item, such as the regular price and a sale price. You can add functionality to Google Ads dynamic ads in Google Web Designer to determine which price should display for each feed item.
Learn more about creating dynamic ads for Google Ads in Google Web Designer.
Display a single price for each item
If your feed contains only a single price for each item, bind the text content of the price element to the price attribute you want to display, such as Retail 0 > Regular price.
Display the sale price alongside the regular price
You can use code to determine how to display prices, depending on whether an item has a sale price and whether the sale price differs from the regular price. In the example below, the item on sale has the sale price displayed below the regular price, which is shown in strikethrough.
The following responsive templates for Google Ads already include this functionality:
- Dynamic Remarketing Single Page with Panels and Individual CTA Buttons
- Dynamic Remarketing with Aligned Panels and Individual CTA Buttons
- Dynamic Remarketing with Headline and Individual CTA Buttons
- Dynamic Remarketing with Headline and Single CTA Button
- Dynamic Remarketing with Pagination and Single CTA
- Dynamic Remarketing with Single CTA II
Otherwise, if you're comfortable using Google Web Designer in Code view, you can add the necessary code by following the steps below. This process works for the Retail dynamic schema, but you may be able to adapt it for other feed types by using different bindings.
1. Create text elements for the prices
Create three text elements in the creative for the following price types:
- Default price - This price displays by itself when there's no sale price.
- Sale price - When provided in the feed, this price displays alongside the regular price.
- Regular price - When the sale price is provided in the feed, this price displays alongside the sale price, usually in strikethrough, so that viewers can compare the two.
All three text elements should share the same parent element.
2. Add bindings
In the Dynamic panel, add dynamic bindings for text content of the price elements to the following data schema objects:
- Default price - Bind to Retail 0 > Lowest price
- Sale price - Bind to Retail 0 > Sale price
- Regular price - Bind to Retail 0 > Regular price
For data schemas other than Retail, you may need to bind the default price and the regular price to the same data schema object.
3. Add classes
In Code view, add the following classes:
- Parent element that contains the prices - Add the class
js-item
to the parent element. If your prices are part of a Swipeable Gallery group, add this class to the group instance. - Default price - Add the class
js-item-price
to the text element. - Sale price - Add the class
js-item-saleprice
to the text element. - Regular price - Add the class
js-item-regularprice
to the text element.
4. Add functions
In Code view, copy and paste the appropriate code from below into your document inside the <head>
tag, depending on whether your items are displayed in a Swipeable Gallery or not.
Functions if there's a Swipeable Gallery
This code assumes that your Swipeable Gallery has the ID of swipegallery-items
. If this isn't the case, change the highlighted text to the correct ID.
<script>
initItemDisplay_ = function(item) {
gwd.myGallery = document.getElementById('swipegallery-items');
elems = document.querySelectorAll('#' + gwd.myGallery.id + ' [data-gwd-grp-id=item-name]');
elemsCta = document.querySelectorAll('#' + gwd.myGallery.id + ' [data-gwd-grp-id=cta-on]');
var itemPrice = item.querySelector('.js-item-price');
var itemSalePrice = item.querySelector('.js-item-saleprice');
var itemRegularPrice = item.querySelector('.js-item-regularprice');
displayCorrectPrices(itemPrice, itemSalePrice, itemRegularPrice);
// turn off all item highlights.
for (let i = 0; i < elems.length; i++) {
elems[i].style.opacity = 0;
}
};
displayCorrectPrices = function(defaultPrice, salePrice, regularPrice) {
var priceValues = {
defaultPrice: defaultPrice && defaultPrice.textContent || null,
salePrice: salePrice && salePrice.textContent || null,
regularPrice: regularPrice && regularPrice.textContent || null
};
showSalePrice(true, defaultPrice, salePrice, regularPrice);
if (isSalePriceEnabled_(priceValues)) {
showSalePrice(true, defaultPrice, salePrice, regularPrice);
} else {
showSalePrice(false, defaultPrice, salePrice, regularPrice);
}
function showSalePrice(state, defaultPrice, salePrice, regularPrice) {
showElement(defaultPrice, !state);
showElement(salePrice, state);
showElement(regularPrice, state);
function showElement(el, state) {
if (!el) return;
if (state) {
el.style.opacity = 1;
el.style.visibility = 'visible';
} else {
el.style.opacity = 0;
el.style.visibility = 'hidden';
}
};
};
function isSalePriceEnabled_(item) {
var isEnabled = item.salePrice && item.regularPrice &&
!isEmptyString(item.salePrice) && !isEmptyString(item.regularPrice) &&
stringValuesAreUnique(item.salePrice, item.regularPrice);
return isEnabled;
function isEmptyString(str) {
if (!str) {
return true;
}
str = str.trim();
return !str || !str.length;
};
function stringValuesAreUnique(value1, value2) {
var valuesNotEqual = value1 != value2;
var valuesBothEmpty = isEmptyString(value1) && isEmptyString(value2);
return valuesNotEqual && !valuesBothEmpty;
};
};
};
</script>
Functions if there's no Swipeable Gallery
<script>
initItemDisplay_ = function(item) {
var itemPrice = item.querySelector('.js-item-price');
var itemSalePrice = item.querySelector('.js-item-saleprice');
var itemRegularPrice = item.querySelector('.js-item-regularprice');
displayCorrectPrices(itemPrice, itemSalePrice, itemRegularPrice);
};
displayCorrectPrices = function(defaultPrice, salePrice, regularPrice) {
var priceValues = {
defaultPrice: defaultPrice && defaultPrice.textContent || null,
salePrice: salePrice && salePrice.textContent || null,
regularPrice: regularPrice && regularPrice.textContent || null
};
showSalePrice(true, defaultPrice, salePrice, regularPrice);
if (isSalePriceEnabled_(priceValues)) {
showSalePrice(true, defaultPrice, salePrice, regularPrice);
} else {
showSalePrice(false, defaultPrice, salePrice, regularPrice);
}
function showSalePrice(state, defaultPrice, salePrice, regularPrice) {
showElement(defaultPrice, !state);
showElement(salePrice, state);
showElement(regularPrice, state);
function showElement(el, state) {
if (!el) return;
if (state) {
el.style.opacity = 1;
el.style.visibility = 'visible';
} else {
el.style.opacity = 0;
el.style.visibility = 'hidden';
}
};
};
function isSalePriceEnabled_(item) {
var isEnabled = item.salePrice && item.regularPrice &&
!isEmptyString(item.salePrice) && !isEmptyString(item.regularPrice) &&
stringValuesAreUnique(item.salePrice, item.regularPrice);
return isEnabled;
function isEmptyString(str) {
if (!str) {
return true;
}
str = str.trim();
return !str || !str.length;
};
function stringValuesAreUnique(value1, value2) {
var valuesNotEqual = value1 != value2;
var valuesBothEmpty = isEmptyString(value1) && isEmptyString(value2);
return valuesNotEqual && !valuesBothEmpty;
};
};
};
</script>
5. Add an event
In Design view, go to the Events panel and add a new event to trigger the code from the previous step. Configure the event according to one of the tables below, depending on whether you have a Swipeable Gallery or not:
Event if there's a Swipeable Gallery
If necessary, change the ID for your Swipeable Gallery in the custom code.
Target | swipegallery-items |
---|---|
Event | Swipeable Gallery > Images loaded |
Action | Custom > Add custom action |
Custom Code | var gallery = document.getElementById('swipegallery-items'); |
Event if there's no Swipeable Gallery
Target | page1 |
---|---|
Event | Page > Ready to present the page |
Action | Custom > Add custom action |
Custom Code | var items = document.querySelectorAll('.js-item'); |