Skip to main content

Howdy Customer Tag Discount Integration Guide

Here is our guide for Howdy Customer Tag Discount integration with Boost AI Search & Discovery app.

Updated this week

📖 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 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.

  1. From your Shopify admin, go to Online Store > Themes

  2. Find the theme you'd like to integrate the app and click Actions (⋯) > Edit code

  3. 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>
  4. Click Save.

  5. Go to Boost app's admin, go to Integration > Template library.

  6. Find your preferred template > click (⋯) > Edit code.

  7. 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 %}
  8. (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 %}
  9. 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);
    }

  10. 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.

Did this answer your question?