Skip to main content

Product Discounts - Targeting Strategies

Advanced techniques for selecting which products receive discounts.

Targeting Overview

Product discounts support multiple targeting strategies:
  1. Direct Targeting: IDs, handles, vendors (simple, fast)
  2. Selector-Based: JMESPath/filters (flexible, powerful)
  3. Combination: Mix multiple strategies

Direct Targeting Methods

By Product Handle

Target specific products by URL-friendly handle:
{
  "handles": ["cool-t-shirt", "awesome-jeans"]
}
When to use:
  • Known product handles
  • Small, specific product sets
  • Performance-critical scenarios

By Variant ID

Most specific targeting method:
{
  "variant_ids": [12345678, 87654321]
}
When to use:
  • Specific sizes/colors
  • Exact variant targeting
  • Integration with external systems

By Vendor

All products from specific brands:
{
  "vendors": ["Nike", "Adidas", "Puma"]
}
When to use:
  • Brand-specific sales
  • Vendor agreements
  • Multi-brand discounts

By Variant Title

Target by size, color, or other options:
{
  "variant_titles": ["Large", "X-Large", "XX-Large"]
}
When to use:
  • Size-specific discounts
  • Color-based pricing
  • Option-based sales

Selector-Based Targeting

Use selector parameter with JMESPath or filter syntax for complex queries.

Basic Selector

{
  "selector": "cart.lines[?merchandise.product.handle=='t-shirt'].id"
}
Returns array of line IDs where product handle is ‘t-shirt’.

Collection-Based Selection

Target all items in a collection:
{
  "facts": {
    "sale_items": "cart.lines[?merchandise.product.collections[?handle=='sale']].id"
  },
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "selector": "$sale_items",
        "discount_type": "percentage",
        "value": 25
      }
    }
  ]
}
How it works:
  1. Query finds lines where product is in ‘sale’ collection
  2. Extracts line IDs
  3. Applies discount to those lines

Tag-Based Selection

Target products with specific tags:
{
  "facts": {
    "clearance_items": "cart.lines[?merchandise.product.tags[?@ == 'clearance']].id"
  },
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "selector": "$clearance_items",
        "discount_type": "percentage",
        "value": 50
      }
    }
  ]
}

Price Range Selection

Target products in specific price range:
{
  "facts": {
    "premium_items": "cart.lines[?merchandise.priceV2.amount >= `100`].id"
  },
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "selector": "$premium_items",
        "discount_type": "fixed_amount",
        "value": 20,
        "message": "$20 Off Premium Items"
      }
    }
  ]
}

Multiple Criteria Selection

Combine multiple conditions:
{
  "facts": {
    "targeted_items": "cart.lines[?merchandise.product.vendor=='Nike' && merchandise.product.collections[?handle=='sale']].id"
  },
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "selector": "$targeted_items",
        "discount_type": "percentage",
        "value": 30
      }
    }
  ]
}
Targets: Nike products that are also in the sale collection.

Selector Syntax Reference

JMESPath Filtering

"cart.lines[?{condition}].id"
Common conditions:
  • merchandise.product.handle == 'value': Exact match
  • merchandise.product.vendor == 'Nike': Vendor match
  • merchandise.priceV2.amount >= 100“: Price comparison
  • merchandise.product.tags[?@ == 'sale']: Array contains
  • merchandise.product.collections[?handle=='sale']: Nested array query

Custom Filter Syntax

Alternative to JMESPath:
"cart.lines | select(merchandise.product.handle == 'shirt') | map(id)"
Filters:
  • select(): Filter items
  • map(): Extract property
  • sum(): Aggregate values

Targeting Decision Guide

Need to target...
├─ Specific known products?
│  └─ Use: handles or variant_ids
├─ All from a brand?
│  └─ Use: vendors
├─ Products in a collection?
│  └─ Use: selector with collection query
├─ Products with specific tags?
│  └─ Use: selector with tag query
├─ Products by price range?
│  └─ Use: selector with price filter
└─ Complex multi-criteria?
   └─ Use: selector with combined conditions

Performance Considerations

Fastest (use when possible)

  1. variant_ids: Direct ID lookup
  2. handles: Simple string match
  3. vendors: Indexed field lookup

Moderate

  1. selector with simple conditions: Single field filter

Slower (use when necessary)

  1. selector with nested queries: Collection/tag traversal
  2. selector with multiple conditions: Complex logic
Optimization tips:
  • Cache selector results in facts
  • Use direct targeting when product set is known
  • Test with realistic cart sizes

Advanced Patterns

Exclude Products

Target all except specific products:
{
  "facts": {
    "discountable_items": "cart.lines[?merchandise.product.handle != 'gift-card'].id"
  },
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "selector": "$discountable_items",
        "discount_type": "percentage",
        "value": 10
      }
    }
  ]
}

Metafield-Based Targeting

Target using custom metafields:
{
  "facts": {
    "b2b_items": "cart.lines[?merchandise.product.metafields[?namespace=='custom' && key=='b2b_eligible'].value == 'true'].id"
  },
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "selector": "$b2b_items",
        "discount_type": "percentage",
        "value": 25,
        "message": "B2B Wholesale Pricing"
      }
    }
  ]
}

Conditional Targeting

Different products based on customer:
{
  "rules": [
    {
      "conditions": {
        "customer.tags": { "includes": "VIP" }
      },
      "facts": {
        "vip_items": "cart.lines[?merchandise.product.vendor == 'Premium Brand'].id"
      },
      "events": [
        {
          "discount": "product_discount",
          "params": {
            "selector": "$vip_items",
            "discount_type": "percentage",
            "value": 30
          }
        }
      ]
    }
  ]
}

Next Steps