Joint session with Vercel: How to build intelligent storefronts (May 15th)

Headless Sanity/Shopify: Product Bundles with Dynamic Discounts

16 repliesLast updated: Dec 2, 2025

Hi all, has anyone worked on a bundle/packs type feature in headless sanity/shopify?
We’re basically looking for:

1. Take existing product skus
2. Bundle them into a 1 price product
3. Discount the bundle to price set in sanity (aka would need a discount applied on shopify)
4. Automatic suggesting add products to cart based on having 1 in cart, aka add a tshirt, suggest hoodie for a 5 euro discount already applied
We thought of using shopfy automatic discounts but you can only have 1 apply per product.


Here’s how it would work for clothing :
AI Update

I've worked on similar Shopify + Sanity bundle implementations! This is definitely achievable, though there are some important considerations about how Shopify handles bundles and discounts in headless contexts.

The Bundle Challenge with Headless Shopify

The tricky part is that Shopify's native Bundles app and discount stacking work differently in headless storefronts compared to their hosted checkout. The Shopify Bundles app is primarily designed for Shopify's hosted storefront, and when using the Storefront API in a headless setup, you'll need to build much of the bundle logic yourself.

Here's how I'd approach your requirements:

1. Model Bundles in Sanity

Create a bundle document type in Sanity that references your Shopify products:

{
  name: 'productBundle',
  type: 'document',
  fields: [
    {
      name: 'title',
      type: 'string'
    },
    {
      name: 'bundleProducts',
      type: 'array',
      of: [{
        type: 'object',
        fields: [
          {name: 'sku', type: 'string'},
          {name: 'quantity', type: 'number'}
        ]
      }]
    },
    {
      name: 'bundlePrice',
      type: 'number'
    },
    {
      name: 'discountAmount',
      type: 'number'
    }
  ]
}

2. Sync to Shopify with Functions or Webhooks

When you create or update bundles in Sanity, you'll need to sync this information to Shopify. You have a few options:

Option A: Sanity Functions (Recommended)

Sanity Functions are serverless compute functions that run on Sanity's infrastructure in response to document events. This is the modern approach for handling content changes without needing your own hosting infrastructure.

With Functions, you can:

Functions are defined in Blueprints and can be deployed using the Sanity CLI. They run on Node.js v22 and support TypeScript. While they're powerful for this use case, be aware they're still being actively developed with APIs that may evolve.

Option B: Webhooks

Sanity webhooks can trigger your own hosted endpoint when bundle documents change. Webhooks use GROQ filters and projections, allowing you to customize exactly which changes trigger notifications and what data gets sent in the payload.

Your endpoint would then call Shopify's Admin API. This requires hosting your own endpoint but gives you complete control over the integration logic.

Option C: Scheduled Sync

Run a scheduled job (via cron or similar) that queries Sanity for bundle changes and syncs to Shopify. Less real-time but more predictable for production environments.

3. Bundle Discount Strategy

Since Shopify's automatic discounts have limitations (especially the "one per product" issue you mentioned), here are two approaches:

Option A: Dynamic Discount Codes

Option B: Cart-level Price Adjustments

4. Smart Product Suggestions

For your "add t-shirt, suggest hoodie" feature, model these relationships in Sanity:

{
  name: 'productSuggestion',
  type: 'document',
  fields: [
    {
      name: 'triggerProduct',
      type: 'reference',
      to: [{type: 'product'}]
    },
    {
      name: 'suggestedProducts',
      type: 'array',
      of: [{
        type: 'object',
        fields: [
          {name: 'product', type: 'reference', to: [{type: 'product'}]},
          {name: 'discountAmount', type: 'number'},
          {name: 'discountType', type: 'string', options: {list: ['percentage', 'fixed']}}
        ]
      }]
    }
  ]
}

In your storefront:

Implementation Flow

Why This Approach Works

By managing bundle logic and product relationships in Sanity, you get:

Sanity's composable architecture is built for exactly this kind of headless e-commerce scenario where you need content flexibility beyond what Shopify's CMS provides.

Technical Note on Shopify Limitations

The challenge with headless Shopify is that many of their newer features (like the Bundles app) are tightly coupled to their hosted checkout experience. The Shopify Storefront API provides access to products and cart functionality, but bundle-specific features aren't fully exposed for headless implementations.

For headless, you're essentially building a custom cart experience anyway, so treating bundles as a content/pricing concern (managed in Sanity) rather than a pure Shopify product concern often gives you more control.

The discount stacking limitation you mentioned is real - Shopify's automatic discounts have complex rules about combining. Using programmatically generated discount codes gives you more flexibility than relying solely on Shopify's automatic discount system, though you'll need to implement the logic for which discounts can stack.

Hope this helps! Let me know if you need clarification on any part of the implementation.

Show original thread
16 replies

Was this answer helpful?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Related contributions