Skip to content
Minimum and Maximum Quantity Rules v2 (Dawn v15 compatible) - Free Tutorial
Browse other ways to boost conversion rate & profit

Minimum and Maximum Quantity Rules v2 (Dawn v15 compatible) - Free Tutorial

Want personalized guidance adding this to your store?

Check out our Insiders community: https://www.skool.com/the-prompted

Members of The Prompted community receive a detailed store audit, 1-on-1 guidance for implementing new features, and access to an exclusive theme. You'll also get marketing support, the same tactics we use to spend over $100k/mo on Meta Ads.

---

In this tutorial, we’re adding a feature that lets you set minimum and maximum quantities for products on your Shopify store. Whether it’s for special promotions or limited-edition items, this customization helps you control how much customers can add to their carts. Best of all, we’ll show you how to implement it for free—no app or developer needed.

Compatible Themes: This code should work on all free Shopify themes (Dawn, Refresh, Craft, Studio, Publisher, Crave, Origin, Taste, Colorblock, Sense, Ride, Spotlight).

 

Create metaobject and metafields

  • Create Quantity Rule metaobject with fields:
    • name
      • Type: single line text
      • Required
    • increment
      • Type: integeter
      • Required
      • min value 1
    • min
      • Type: integer
      • required
      • min value 1
    • max
      • Type: integer
      • Min value 1
  • Create Product Metafield
    • Name: Quantity Rule
    • Type: Metaobject (Quantity Rule)
  • Create Variant Metafield
    • Name: Quantity Rule
    • Type: Metaobject (Quantity Rule)
  • Create metaobject entries for each set of rules
  • Create Product Metafield
    • Name: Quantity Rule Type Override
    • Type: Single Line Text
    • Limit to preset choices:
      • Product Rules
      • Variant Rules

Edit Theme Code

Edit settings_schema.json

  {
    "name": "Custom Quantity Rules",
    "settings": [
      {
        "type": "checkbox",
        "id": "use_quantity_rules",
        "label": "Enable custom quantity rules",
        "default": false
      },
      {
        "type": "select",
        "id": "qty_rule_type",
        "options": [
          {
            "value": "product_rule",
            "label": "Product Rules"
          },
          {
            "value": "variant_rule",
            "label": "Variant Rules"
          }
        ],
        "label": "Quantity Rule Type",
        "info": "Specify whether quantity rules are applied at the product level or variant level",
        "default": "variant_rule"
      }
    ]
  }

Edit main-cart-items.liquid and cart-drawer.liquid

  • Replace item.variant.quantity_rule with quantity_rule
  • Add the following code:
    {%- if settings.use_quantity_rules -%}
      {% if item.product.metafields.custom.quantity_rule_type_override == "Product Rules" %}
        {% assign quantity_rule_type = "product_rule" %}
      {% elsif item.product.metafields.custom.quantity_rule_type_override == "Variant Rules" %}
        {% assign quantity_rule_type = "variant_rule" %}
      {% elsif settings.qty_rule_type == "product_rule" %}
        {% assign quantity_rule_type = "product_rule" %}
      {% elsif settings.qty_rule_type == "variant_rule" %}
        {% assign quantity_rule_type = "variant_rule" %}
      {% endif %}
      {% if quantity_rule_type == "product_rule" %}
        {% assign quantity_rule = item.product.metafields.custom.quantity_rule.value %}
        {% assign total_product_quantity = 0 %}
        {% assign global_max = item.product.metafields.custom.quantity_rule.value.max | plus: 0 %}
        {% for cart_item in cart.items %}
          {% if cart_item.product.id == item.product.id %}
            {% assign total_product_quantity = total_product_quantity | plus: cart_item.quantity %}
          {% endif %}
        {% endfor %}
        {% assign item_remaining_qty = global_max | minus: total_product_quantity %}
        {% assign max_for_variant = item.quantity | plus: item_remaining_qty %}
        {% if max_for_variant > global_max %}
          {% assign max_for_variant = global_max %}
        {% endif %}
       {% elsif quantity_rule_type == "variant_rule" %}
         {% assign quantity_rule = item.variant.metafields.custom.quantity_rule.value %}
      {% endif %}
      {% if quantity_rule == nil %}
        {% assign quantity_rule = item.variant.quantity_rule %}
      {% endif %}
    {% else %}
      {% assign quantity_rule = item.variant.quantity_rule %}
    {% endif %}
    
  • Replace the input max max="{{ quantity_rule.max }}” with:
    {% if quantity_rule_type == "product_rule"%}
      max="{{ max_for_variant }}"
    {% else %}
      max="{{ quantity_rule.max }}"
    {% endif %}
    

Edit main-product.liquid

  • Replace product.selected_or_first_available_variant.quantity_rule with quantity_rule
  • Add the following code:
    {% if settings.use_quantity_rules %}
      {% if product.metafields.custom.quantity_rule_type_override == "Product Rules" %}
        {% assign quantity_rule_type = "product_rule" %}
      {% elsif product.metafields.custom.quantity_rule_type_override == "Variant Rules" %}
        {% assign quantity_rule_type = "variant_rule" %}
      {% elsif settings.qty_rule_type == "product_rule" %}
        {% assign quantity_rule_type = "product_rule" %}
      {% elsif settings.qty_rule_type == "variant_rule" %}
        {% assign quantity_rule_type = "variant_rule" %}
      {% endif %}
     {% if quantity_rule_type == "product_rule" %}
       {% assign quantity_rule = product.metafields.custom.quantity_rule.value %}
     {% elsif quantity_rule_type == "variant_rule" %}
       {% assign quantity_rule = product.selected_or_first_available_variant.metafields.custom.quantity_rule.value %}
     {% endif %}
      {% if quantity_rule == nil %}
        {% assign quantity_rule = product.selected_or_first_available_variant.quantity_rule %}
      {% endif %}
    {% else %}
      {% assign quantity_rule = product.selected_or_first_available_variant.quantity_rule %}
    {% endif %}
    {% if settings.use_quantity_rules and quantity_rule_type == "product_rule" %}
      {% assign cart_qty = 0 %}
      {% for item in cart.items %}
        {% if item.product.id == product.id %}
          {% assign cart_qty = cart_qty | plus: item.quantity %}
        {% endif %}
      {% endfor %}
    {% else %}
    
    ... existing cart_qty assignment...
      
    {% endif %}
    
    

Edit product-info.js

Add new method

updateQuantitySelector(html) {
  const newQuantitySelectorContainer = html.querySelector('#Quantity-Form-' + this.sectionId);
  const currentQuantitySelectorContainer = document.querySelector('#Quantity-Form-' + this.dataset.section);
  
  if (newQuantitySelectorContainer && currentQuantitySelectorContainer) {
    const newContent = newQuantitySelectorContainer.innerHTML.trim();
    
    if (newContent === '') {
      return;
    }
    
    currentQuantitySelectorContainer.innerHTML = newContent;
    
    this.quantityInput = currentQuantitySelectorContainer.querySelector('.quantity__input');
    this.initQuantityHandlers();
  }
}

Call new method and comment out this.updateQuantityRules(this.sectionId, html); in method handleUpdateProductInfo

this.updateQuantitySelector(html);
//this.updateQuantityRules(this.sectionId, html);

Edit quantity-popover.js

In method togglePopover, replace this.infoButtonDesktop.classList.add with button.classList.add

button.classList.add('quantity-popover__info-button--icon-only--animation');

In method closePopover, reorder const button definition so that it’s above the const isButtonChild definition, and replace this.infoButtonDesktop.contains with button.contains

        const button = this.infoButtonDesktop && this.mql.matches ? this.infoButtonDesktop : this.infoButtonMobile;
        
        const isButtonChild = button.contains(event.relatedTarget);
        const isPopoverChild = this.popoverInfo.contains(event.relatedTarget);

In method closePopover, replace this.infoButtonDesktop.classList.remove with button.classList.remove

button.classList.remove('quantity-popover__info-button--icon-only--animation');

 

 

Browse other ways to boost conversion rate & profit