Aug 29, 2024
5
min. Reading Time

How to Create Quantity Discounts Natively in Shopify for Free

How to Create Quantity Discounts Natively in Shopify for Free

How to Create Quantity Discounts Natively in Shopify for Free

Zakaria @ Beehive Apps

Shopify App Developer

How to add a Quantity Discounts widget to your store for FREE
How to add a Quantity Discounts widget to your store for FREE
How to add a Quantity Discounts widget to your store for FREE

Quantity breaks can be an effective way to encourage customers to purchase more by offering discounts based on the quantity of items they buy. As the creator of Bundle Bee, a premium app for Shopify that allows you to easily create quantity discounts and bundles, I understand how valuable this functionality can be for store owners.

I created this guide because I believe it would be amazing to have this basic functionality available by default for Shopify stores. While Bundle Bee offers a robust, user-friendly solution for a monthly fee, I also want to show you how you can achieve similar results for free, provided you have some basic technical knowledge.

In this guide, we’ll walk you through setting up simple quantity breaks natively in Shopify. This method is suitable for small stores with straightforward discount configurations and can be a bit complex if you’re not familiar with adding custom code to your theme, but it’s completely doable with a little guidance.

1. Creating Automatic Discounts

To begin, you'll need to create an automatic discount for each quantity break you want to offer. For example, if you want to offer a discount for purchasing 2 items ("Duo") and another for 3 items ("Trio"), you’ll create two separate discounts.

Steps to Create Automatic Discounts:

Go to the Discounts Page:

  • In your Shopify Admin, navigate to Discounts.

  • Click on Create Discount and select Amount off products.

    Instructions to find the correct settings

Create the "Duo" Discount:

  • Choose Automatic discount for the method setting.

  • Name the discount "Duo" (Customers will see this in their cart and at checkout).

  • Set the discount amount to 20% (or your desired percentage).

  • In the Applies to settings section, select Specific products and make sure to select the products this quantity discount should apply to.

  • In the Minimum purchase requirements settings section, click on the Minimum quantity of items radio button and then enter the minimum quantity that should be purchased in order for a the discount to be triggered on a product. In our example we will set it to 2.

  • Combinations are up to you, depending on whether or not you'd like this discount to combine with other types of discounts that you can create in your Shopify store.

Instructions to find the correct settings

Create the "Trio" Discount:

  • Follow the same steps as above to create a "Trio" discount that offers a 30% off discount when the quantity is 3 or greater.

Repeat for Additional Breaks:

  • If you have more quantity breaks, repeat the process for each one, adjusting the minimum quantity and discount according to your needs.

2. Create a Quantity Break Metaobject Definition

Metaobjects are custom data structures in Shopify that allow you to store and manage additional information for your products.

Steps to Create a Quantity Break Metaobject Definition:

Access Shopify Admin:

  • Navigate to Settings > Custom Data > Metaobject definitions.

  • Click on the Add Definition button (I have already created mine as you can see in the image below).

    Instructions to find the correct settings

Create a New Metaobject Definition:

  • Name it Quantity Break (I have already done this step in the screenshot above, but

Instructions to find the correct settings

Add the fields to the Metaobject Definition:

  • Make sure the names and settings perfectly match the ones shown below in order for this to work correctly.

  • Deal title:

    Instructions to find the correct settings
  • Deal subtitle

    Instructions to find the correct settings
  • Minimum Quantity

    Instructions to find the correct settings
  • Discount amount (%)

    Instructions to find the correct settings
  • Badge content

    Instructions to find the correct settings

Save the Metaobject Definition:

  • After adding all necessary fields, make sure to save the definition.

3. Create a Quantity Breaks List Metaobject Definition

Next, you’ll create a metaobject that acts as a list to hold multiple quantity breaks on your products. This will only make sure that the quantity breaks widget, that we will create later, correctly displays, but it doesn't add any actual discount to the product (the Shopify automatic discounts we created initially are the ones that make sure the discount is added in the cart and checkout).

Steps to Create a Quantity Breaks List Metaobject Definition:

Navigate to Settings > Custom Data > Products:

Instructions to find the correct settings

Create a New Metaobject Definition:

  • Click on the Add Definition button.

  • IMPORTANT: Make sure to name it Quantity Breaks List and that the namespace and key are called custom.quantity_breaks_list.

    Instructions to find the correct settings
  • Click on Select type > Metaobject.

    Instructions to find the correct settings
  • Click on Select metaobject > Quantity Break (the metaobject we created earlier).

    Instructions to find the correct settings
  • Click on List of entries. This allows us to add multiple Quantity Break metaobjects inside the one we are creating. Optionally you can also make your products filterable using this metaobject by toggling the Filter in product index setting (see image below).

    Instructions to find the correct settings

Save the Metaobject Definition:

  • Save the new metaobject definition.

4. Add Quantity Break Metaobjects to Products

Now, you'll add quantity break metaobjects to the products that currently have an automatic discount running.

Steps to Add Quantity Break Metaobjects:

Go to Products:

  • Navigate to the Products section in your Shopify Admin.

  • Open the product you want to add quantity breaks to.

Add Quantity Breaks:

  • Scroll to the Metafields section of the product.

  • Add a new "Quantity Break" metaobject to the "Quantity Breaks List" metaobject. I know, it can be confusing, but you'll get a hang of it the more you play around with it.

    Instructions to find the correct settings
  • I will add two Quantity Break metaobjects to the list, one will be called Duo and the other Trio. The order in which you add them will determine how they are displayed on the product page.

    • Duo:

      Instructions to find the correct settings
    • Trio:

      Instructions to find the correct settings

Save the Product:

  • Once you've added the quantity breaks, save the product.

5. Add the Code as a Snippet in the Theme

This is the part where it gets technical and a bit more complex. But it's something you have to do once and you'll be able to reuse it in the theme editor without the need to dive into the code. To display the quantity breaks on the product page, you need to add a code snippet to your theme.

Steps to Add the Snippet:

Go to Themes:

  • In your Shopify Admin, navigate to Online Store > Themes.

  • Click on Actions > Edit Code for your active theme.

    Instructions to find the correct settings

Create a New Snippet:

  • In the Snippets folder, click Add a new snippet.

  • Name the snippet "quantity-breaks".

    Instructions to find the correct settings

Add the Code:

  • Paste the Liquid, HTML, CSS, and JavaScript code for the quantity breaks you can find below into this snippet and then make sure to save the snippet.

{% assign has_quantity_breaks = false %}
{% for quantity_break in product.metafields.custom.quantity_breaks_list.value %}
  {% assign has_quantity_breaks = true %}
  {% break %}
{% endfor %}

{% if has_quantity_breaks %}
<style>
  .quantity-breaks-widget {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  
  .quantity-break {
    border: 1px solid #ddd;
    padding: 15px;
    border-radius: 5px;
    position: relative;
    display: flex;
    align-items: center;
  }
  
  .quantity-break.active {
    border: 2px solid #000;
  }
  
  .quantity-break input[type="radio"] {
    display: none;
  }
  
  .quantity-break label {
    cursor: pointer;
    width: 100%;
  }
  
  .deal-title {
    font-size: 1.2em;
    font-weight: bold;
  }
  
  .deal-subtitle {
    font-size: 0.9em;
    color: #888;
  }
  
  .discounted-price {
    font-size: 1.1em;
    font-weight: bold;
    color: #000;
    margin-top: 5px;
  }
  
  .original-price {
    text-decoration: line-through;
    font-size: 0.9em;
    color: #aaa;
    margin-left: 5px;
  }

  .quantity-break-badge {
    position: absolute;
    top: -5px;
    right: 10px;
    background-color: #000;
    color: #fff;
    padding: 2px 10px;
    border-radius: 3px;
    font-size: 0.8em;
    font-weight: bold;
    z-index: 1;
  }
</style>

<div class="quantity-breaks-widget">
  {% for quantity_break in product.metafields.custom.quantity_breaks_list.value %}
  {% assign minimum_quantity = quantity_break.minimum_quantity %}
  {% assign discount_amount = quantity_break.discount_amount | divided_by: 100 %}
  {% assign original_price = product.price | times: minimum_quantity %}
  {% assign discount_price = original_price | times: discount_amount %}
  {% assign final_price = original_price | minus: discount_price %}

  <div class="quantity-break" data-quantity="{{ minimum_quantity }}">
    {% if quantity_break.badge_content != blank %}
      <div class="quantity-break-badge">{{ quantity_break.badge_content }}</div>
    {% endif %}
    <input type="radio" id="quantity-break-{{ forloop.index }}" name="quantity-break" data-quantity="{{ minimum_quantity }}">
    <label for="quantity-break-{{ forloop.index }}">
      <div class="deal-title">{{ quantity_break.deal_title }}</div>
      <div class="deal-subtitle">{{ quantity_break.deal_subtitle }}</div>
      <div class="discounted-price">
        {{ final_price | money }}
        {% if discount_amount > 0 %}
        <span class="original-price">{{ original_price | money }}</span>
        {% endif %}
      </div>
    </label>
  </div>
  {% endfor %}
</div>

<script>
document.addEventListener("DOMContentLoaded", function() {
  const quantityInput = document.querySelector('input[name="quantity"]');
  const currentQuantity = quantityInput ? parseInt(quantityInput.value, 10) : 1;

  const quantityBreaks = document.querySelectorAll('.quantity-break');
  let activeFound = false;

  quantityBreaks.forEach(function(breakElement) {
    const quantity = parseInt(breakElement.getAttribute('data-quantity'), 10);

    if (quantity === currentQuantity) {
      breakElement.classList.add('active');
      breakElement.querySelector('input[name="quantity-break"]').checked = true;
      activeFound = true;
    }

    breakElement.querySelector('input[name="quantity-break"]').addEventListener('change', function(event) {
      if (event.target.checked) {
        // Remove active class from all deals
        document.querySelectorAll('.quantity-break.active').forEach(function(activeElement) {
          activeElement.classList.remove('active');
        });

        // Add active class to the selected deal
        breakElement.classList.add('active');

        // Update the quantity input
        quantityInput.value = quantity;

        // Dispatch a custom event with metadata
        const customEvent = new CustomEvent('change', {
          bubbles: true,
          detail: { dispatchedBy: 'quantity-break-script' }  // Adding metadata
        });
        quantityInput.dispatchEvent(customEvent);
      }
    });
  });

  // If no matching quantity break was found, default to the first deal
  if (!activeFound && quantityBreaks.length > 0) {
    quantityBreaks[0].classList.add('active');
    quantityBreaks[0].querySelector('input[name="quantity-break"]').checked = true;

    // Set the quantity input to the first deal's quantity
    const firstQuantity = quantityBreaks[0].getAttribute('data-quantity');
    quantityInput.value = firstQuantity;

    // Dispatch a custom event with metadata
    const customEvent = new CustomEvent('change', {
      bubbles: true,
      detail: { dispatchedBy: 'quantity-break-script' }  // Adding metadata
    });
    quantityInput.dispatchEvent(customEvent);
  }

  // Listen for changes to the quantity input
  quantityInput.addEventListener('change', function(event) {
    // Check if this change event was dispatched by our script
    console.log(event)
    if (event.detail && event.detail.dispatchedBy === 'quantity-break-script') {
      // Do nothing, since it's our own event
      return;
    }

    // Handle other cases, like syncing deals with manually changed quantity
    const newQuantity = parseInt(quantityInput.value, 10);

    // Find the deal that matches the new quantity and set it as active
    quantityBreaks.forEach(function(breakElement) {
      const quantity = parseInt(breakElement.getAttribute('data-quantity'), 10);
      if (quantity === newQuantity) {
        //Only remove the active class if we are sure we found a matching deal. Otherwise let's just leave the previous one selected
        document.querySelectorAll('.quantity-break.active').forEach(function(activeElement) {
          activeElement.classList.remove('active');
        });
        
        breakElement.classList.add('active');
        breakElement.querySelector('input[name="quantity-break"]').checked = true;
      }
    });
  });
});
</script>
{

6. Add Block to Product Section and Render the Snippet

Next (and last complex step), you need to add the snippet to your product page template. I highly suggest getting a Shopify developer to follow these last steps, as you can easily break your store by simply forgetting a comma.

Steps to Add the Block:

Edit the Product Section:

  • Still in the theme code editor, locate your main product section. In my theme (Taste) and many other themes this is called main-product.liquid in the sections folder.

    Instructions to find the correct settings

Add a Block for the Snippet:

  • Use command+f (control+f on Windows) to activate the search feature in this file and look for this exact piece of code "blocks":(quotation marks and colon included).

  • Then add the following code:

{
    "type": "quantity_breaks",
    "name": "Quantity Breaks"
},
  • It should look like the following screenshot:

    Instructions to find the correct settings
  • Now using the search tool, just like we did earlier look for this exact piece of code for block in section.blocks and then add this code and make sure it looks like the screenshot below:

    Instructions to find the correct settings
{%- when 'quantity_breaks' -%}
  {% render 'quantity-breaks' %}

Save the Changes:

  • Save your changes to the product section file.

7. Add the Block to the Product Page in the Theme Editor

Finally, you’ll need to ensure that the block is enabled in your theme’s customizer.

Steps to Enable the Block:

Go to Theme Editor:

  • Navigate to Online Store > Themes.

  • Click on Customize for your active theme.

    Instructions to find the correct settings

Add the Block:

  • In the customizer, navigate to a product page.

  • Add the new "Quantity Breaks" block to the product section.

Instructions to find the correct settings

Save the Layout:

  • Save your changes in the theme editor.

  • Navigate to the product you added the automatic discount and the Quantity Break metaobjects and you should be able to see the widget display correctly.

Working quantity discounts widget in Shopify storefront product page

Limitations and Maintenance Considerations

While this approach gets the job done for small stores with simple discount configurations, it comes with a few limitations:

  • Manual Setup: Each discount must be manually created and linked to the products and the correct metaobjects assigned to the product, which can become tedious as your store grows.

  • Limited Functionality: This method only supports basic discount configurations and lacks features like advanced customizations, dynamic pricing display, and multi-language support.

  • Maintenance: Managing and updating multiple discounts can be time-consuming and prone to errors.

Simplify and Enhance with Bundle Bee - Quantity Breaks App

For larger stores or those looking for more advanced features, my Shopify app, Bundle Bee - Quantity Breaks, offers a powerful and user-friendly solution. Here’s what it brings to the table:

  • Streamlined Setup: Automatically create and manage quantity breaks with an intuitive interface.

  • Advanced Customization: Customize the appearance, behavior, and logic of your quantity breaks to fit your brand.

  • Internationalization (i18n): Easily support multiple languages and currencies, making your store more accessible globally.

  • Real-Time Sync: Ensure that discounts and quantity breaks stay in sync across your store without the need for manual intervention.

How to Get Started with Bundle Bee

  1. Install the App:

  2. Configure Your Quantity Breaks:

    • Use the app's intuitive interface to create and manage your quantity breaks.

    • Customize the appearance and behavior of your quantity breaks to match your store's branding.

  3. Publish to Your Store:

    • Once you’re happy with your settings, publish the quantity breaks to your store with a single click.

  4. Enjoy Enhanced Functionality:

    • Enjoy the benefits of a fully integrated quantity breaks solution that saves you time and enhances your customers' shopping experience.

By following this guide, you should now have a functional quantity breaks setup on your Shopify store. If you're looking to take things to the next level with more advanced features and easier management, be sure to check out Bundle Bee - Quantity Breaks.

Other articles you might like

Other articles you might like

© 2024 Beehive Apps. All rights reserved

© 2024 Beehive Apps. All rights reserved

© 2024 Beehive Apps. All rights reserved