📖 Integrate the Howdy Customer Tag Discount app with Boost AI Search & Discovery to ensure discount tags are displayed seamlessly alongside your Boost-powered products and widgets.
⚠️ IMPORTANT NOTICE
If you experience any issues with the integration, we highly recommend double-checking that you’ve followed all the steps in this guide. Should the issue persist, please reach out to the Howdy support team. Please visit Howdy Customer Tag Discount app listing and click the ‘Get support’ button to contact them directly.
About Howdy Customer Tag Discount
App information
App details: https://apps.shopify.com/customer-tag-discount-app
App function
Howdy Customer Tag Discount allows merchants to create customer-based discounts using Shopify’s customer tags. With this integration, Boost can display these discounts correctly in:
Collection pages
Search results pages
Product recommendations
⚠️ Filter Compatibility Limitation: The Howdy Customer Tag Discount app currently does not support integration with Boost’s Price filter. If you’re using this filter in your storefront, please be aware that discount tags applied through Howdy may not reflect accurately.
How to integrate Howdy Customer Tag Discount with Boost AI Search & Discovery
⚠️ This feature only works with Boost AI Search & Discovery TURBO version. To find out which version of our app your store's current theme is installed with, please follow this article.
From your Shopify admin, go to Online Store > Themes
Find the theme you'd like to integrate the app and click Actions (⋯) > Edit code
Locate the
layout/theme.liquid
file. Cioy and paste this code within the <head> tag:
<!-- Script for Boost app and Howdy app -->
<script>
customerData = {
isLogged: {% if customer != blank %} true {% else %} false {% endif %},
tags: {{ customer.tags | json }}
}
howdyRawMetafields = {{ shop.metafields.howdy-collections-discount-settings.howdy-discount-settings.value | json }};
howdyDiscountValues = {{ shop.metafields.howdy-order-discount-settings.howdy-discount-settings.value | json }};
</script>Click Save.
Go to Boost app's admin, go to Integration > Template library.
Find your preferred template > click (⋯) > Edit code.
Locate the
src/product-item/main.liquid file
, add this code snippet below:{% capture productData %}
{
"handle": "{{ product.handle }}",
"variantId": "{{ product.variant_id }}",
"splitProduct": "{{ product.split_product }}",
{% settings if themeSettings.productItems.productImg.elements.selectOptionBtn.action == 'quickAddToCart' %}
"variants": {{ productVariants | json | escape }},
{% settings endif %}
"priceMin": "{{ product.price_min }}",
"priceMax": "{{ product.price_max }}",
"compareAtPriceMin": "{{ product.compare_at_price_min }}",
"compareAtPriceMax": "{{ product.compare_at_price_max }}",
"images": {{ imageArray | json | escape }},
"options_with_values": {{ product.options_with_values | json | escape }},
"selectedVariantImageByFilterOption": "{{ selectedVariantImageByFilterOption | escape }}",
"category": "{{ product.product_type | escape }}",
"tags" : {{ product.tags | json | escape }},
"collections": {{ product.collections | json | escape }}
}
{% endcapture %}(Optional) If you use Quick View function of Boost app, locate the
src/quickview/main.liquid
file, add this code snippet below:{% capture productData %}
{
"id": "{{ product.id }}",
"handle": "{{ product.handle }}",
"variantId": "{{ product.variant_id }}",
"splitProduct": "{{ product.split_product }}",
"variants": {{ product.variants | json | escape }},
"tags": {{ product.tags | json | escape }},
"images": {{ imageArray | json | escape }},
"category": "{{ product.product_type | escape }}",
"tags" : {{ product.tags | json | escape }},
"collections": {{ product.collections | json | escape }},
"priceMin": "{{ product.price_min }}"
}
{% endcapture %}Finally, locate this file
assets/customization.js
and add this code snippet:/*********************** Custom JS for Boost AI Search & Discovery ************************/
function afterRender() {
try {
const productItems = document.querySelectorAll('.boost-sd__product-item');
if (productItems) {
productItems.forEach((productItem) => {
let productData = productItem.getAttribute('data-product');
const dataProductParsed = JSON.parse(productData);
if (productData) {
productData = JSON.parse(productData);
const calculatedPriceData = calculateProductPrice({
product: dataProductParsed,
customer: customerData,
shopMetafields: {
"howdy-order-discount-settings": {
"howdy-discount-settings": { value: howdyDiscountValues }
},
"howdy-collections-discount-settings": {
"howdy-discount-settings": { value: howdyRawMetafields }
}
}
});
updateProductPrice(productItem, calculatedPriceData, "collection-products");
}
});
}
// Quick Modal
const quickModal = document.getElementById("boost-sd__modal-quickview");
if (quickModal) {
const quickModalProductData = quickModal.getAttribute('data-product');
const quickModalProductParsed = JSON.parse(quickModalProductData);
const calculatedPriceQuickModalData = calculateProductPrice({
product: quickModalProductParsed,
customer: customerData,
shopMetafields: {
"howdy-order-discount-settings": {
"howdy-discount-settings": { value: howdyDiscountValues }
},
"howdy-collections-discount-settings": {
"howdy-discount-settings": { value: howdyRawMetafields }
}
}
});
updateQuickViewPrice(quickModal, calculatedPriceQuickModalData);
const priceContainer = quickModal.querySelector(".boost-sd__quick-view-price");
if (priceContainer) {
const observer = new MutationObserver(() => {
updateQuickViewPrice(quickModal, calculatedPriceQuickModalData);
});
observer.observe(priceContainer, {
childList: true,
subtree: true,
characterData: true
});
}
}
} catch (error) {
console.warn(error);
}
}
// Register the custom function with the scope 'filter'
boostWidgetIntegration.regisCustomization(afterRender, 'filter');
// Register the custom function to apply to all scopes
boostWidgetIntegration.regisCustomization(afterRender);
function calculateProductPrice({
product,
customer,
shopMetafields,
placeholder = false,
settings = { currency_code_enabled: false }
}) {
let compareAtPriceMin = parseFloat(product.compareAtPriceMin);
let compareAtPriceMax = parseFloat(product.compareAtPriceMax);
let moneyPriceMin = parseFloat(product.priceMin);
let moneyPriceMax = parseFloat(product.priceMax);
const discountValues = shopMetafields["howdy-order-discount-settings"]?.["howdy-discount-settings"]?.value || [];
const rawMetafields = shopMetafields["howdy-collections-discount-settings"]?.["howdy-discount-settings"]?.value;
const selectedCollectionIds = rawMetafields?.selectedCollectionIds || [];
let maxDiscountPercent = 0;
if (customer) {
discountValues.forEach((discount) => {
if (customer.tags.includes(discount.tagName)) {
let canApplyDiscount = false;
if (discount.targetCollections.length > 0) {
for (const collection of product.collections) {
const collectionGid = `gid://shopify/Collection/${collection.id}`;
if (discount.targetCollections.includes(collectionGid)) {
canApplyDiscount = true;
break;
}
}
} else if (selectedCollectionIds.length > 0) {
for (const collection of product.collections) {
const collectionGid = `gid://shopify/Collection/${collection.id}`;
if (selectedCollectionIds.includes(collectionGid)) {
canApplyDiscount = true;
break;
}
}
} else {
canApplyDiscount = true;
}
if (canApplyDiscount) {
const currentDiscount = parseFloat(discount.discountPercent) || 0;
if (currentDiscount > maxDiscountPercent) {
maxDiscountPercent = currentDiscount;
}
}
}
});
if (maxDiscountPercent > 0) {
const discountMultiplier = (100 - maxDiscountPercent) / 100;
compareAtPriceMin = moneyPriceMin;
compareAtPriceMax = moneyPriceMax;
moneyPriceMin *= discountMultiplier;
moneyPriceMax *= discountMultiplier;
}
}
return {
compareAtPriceMin,
compareAtPriceMax,
moneyPriceMin,
moneyPriceMax,
maxDiscountPercent
};
}
function updateProductPrice(productItem, calculatedPriceData, target) {
const compareAtPriceMin = calculatedPriceData.compareAtPriceMin ? parseFloat(calculatedPriceData.compareAtPriceMin).toFixed(2) : "0.00";
if (target == "collection-products") {
// howdy
const existingHowdyPrice = productItem.querySelector(".howdy__product-price");
if (existingHowdyPrice) {
existingHowdyPrice.remove();
}
const priceContainer = productItem.querySelector('.boost-sd__product-price');
if (!priceContainer) {
return;
}
// console.log("calculatedPriceData", calculatedPriceData)
const howdyPriceElement = document.createElement('div');
howdyPriceElement.className = 'howdy__product-price';
howdyPriceElement.innerHTML = `
<div class="boost-sd__product-price-wrapper">
<span aria-hidden="true" class="boost-sd__product-price-content boost-sd__product-price-content--row-reverse boost-sd__product-price-content--text-align-center">
<span class="boost-sd__product-price--sale">
<span class="boost-sd__format-currency">$${calculatedPriceData.moneyPriceMin.toFixed(2)}</span>
</span>
<span class="boost-sd__format-currency boost-sd__format-currency--price-compare boost-sd__product-price--compare">
<span class="boost-sd__format-currency">$${compareAtPriceMin}</span>
</span>
</span>
<span aria-hidden="true" class="boost-sd__product-price--saving">
<span class="boost-sd__format-currency">Save $${(compareAtPriceMin - calculatedPriceData.moneyPriceMin).toFixed(2)}</span>
</span>
</div>
`;
priceContainer.style.display = 'none';
priceContainer.parentNode.insertBefore(howdyPriceElement, priceContainer.nextSibling);
}
}
// Quick View
function updateQuickViewPrice(quickModal, calculatedPriceData) {
const priceContainer = quickModal.querySelector(".boost-sd__quick-view-price");
if (!priceContainer) {
return;
}
const existingHowdyPrice = quickModal.querySelector(".howdy__quick-view-price");
if (existingHowdyPrice) {
existingHowdyPrice.remove();
}
const priceElement = priceContainer.querySelector(".boost-sd__format-currency");
if (!priceElement) {
return;
}
const price = parseFloat(priceElement.textContent.replace(/[^0-9.-]+/g, ""));
if (!price || isNaN(price)) {
return;
}
const discountMultiplier = (100 - calculatedPriceData.maxDiscountPercent) / 100;
const discountedPrice = (price * discountMultiplier).toFixed(2);
const savingAmount = (price - discountedPrice).toFixed(2);
const howdyPriceElement = document.createElement('div');
howdyPriceElement.className = 'howdy__quick-view-price';
howdyPriceElement.style.display = 'block';
howdyPriceElement.innerHTML = `
<span class="boost-sd__format-currency">$${discountedPrice}</span>
<span class="boost-sd__format-currency boost-sd__format-currency--price-compare">$${price.toFixed(2)}</span>
<span class="boost-sd__format-currency boost-sd__product-price--saving" style="margin-left: 8px;">Save $${savingAmount}</span>
`;
priceContainer.style.display = 'none';
priceContainer.parentNode.insertBefore(howdyPriceElement, priceContainer.nextSibling);
}Click Save and you're set.
⚠️ Important notes
Ensure customers are logged in with the correct Shopify customer tags to view discounts.
Boost displays discount information based on Howdy’s API data. Changes may take a few minutes to reflect on the storefront.
If discounts are not showing, clear your browser cache or refresh your store theme integration.
Feel free to reach out to our dedicated support team via chat if you have any questions or require additional assistance.