- Structure
- Liquid Section
- Add to Cart Properties
- FoxSell JS Object
- Storefront API
- FoxSell TS Types
Mix and Match Settings Metaobject
Only present in case
Hide fields
Hide fields
ID of the bundle within the app
List of unique product references selected within the app
Category Properties selected within the app
Show fields
Show fields
Title of the Category
Maximum amount of products to be selected from this category.
Only to be used when
Quantity as an option is unchecked.Only present in case
Quantity as an option is checked in the app. Show fields
Show fields
Title of the Option
Integer Variant ID of Quantity Option
Quantity of Products to be selected for this option
List of product references selected as add ons within the app
Object is a Key Value Pair
{key: value}To be used in case
Quantity as an option is uncheckedShow fields
Show fields
List of objects with Key Value pair.
[{key: value}]Quantity as an option is checked in the app. Show fields
Show fields
Bundle Variant GID
Example:
gid://shopify/ProductVariant/XXXXXXXOption Properties
Show fields
Show fields
Title of the Option
Quantity of Products to be selected for this option
Add this snippet as a section in your theme to see the values of the metafieldNote: The
namespace and key are constant for all the storesCopy
{% liquid
assign app_namespace = 'app--67872686081'
assign dynamic_add_ons_bundle_config = product.metafields[app_namespace].dynamic_add_ons_bundle.value
assign bundle_id = dynamic_add_ons_bundle_config.bundle_id
assign options = dynamic_add_ons_bundle_config.options_v2.value
assign products = dynamic_add_ons_bundle_config.products.value
assign add_on_products = dynamic_add_ons_bundle_config.add_on_products.value
assign add_on_product_properties = dynamic_add_ons_bundle_config.add_on_product_properties.value
assign categories = dynamic_add_ons_bundle_config.categories.value
assign settings = dynamic_add_ons_bundle_config.settings.value
%}
<p><strong>Bundle ID</strong>: {{ bundle_id }}</p>
<p><strong>Options:</strong></p>
{% for option in options %}
{{ option | json }}
{% endfor %}
<p><strong>Categories</strong></p>
{% for category in categories %}
<p><strong>Title:</strong> {{ category.title }}</p>
<p><strong>Category Max Quantity (Only used if Options are Empty):</strong> {{ category.quantity }}</p>
<p><strong>Products</strong></p>
{% for p in category.products %}
{% liquid
assign int_product_id = p.id | times: 1
assign product_ref = null
paginate products by 128
for ref in products
if ref.id == int_product_id
assign product_ref = ref
break
endif
endfor
endpaginate
assign product_variants = p.variants
%}
<p><strong>Product ID:</strong> {{ p.id }}</p>
<p><strong>Product Title:</strong> {{ product_ref.title }}</p>
{% for variant_data in product_variants %}
{% liquid
assign variant_id = variant_data[0] | times: 1
assign variant_price = variant_data[1]
assign variant = product_ref.variants | where: 'id', variant_id | first
%}
{% if variant %}
<p><strong>Variant ID:</strong> {{ variant_id }}</p>
<p><strong>Variant Overridden Price:</strong> {{ variant_price }}</p>
<p><strong>Variant Ref:</strong> {{ variant | json }}</p>
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
<p><strong> Add On Products</strong></p>
{% for p in add_on_products %}
{% assign product_gid = 'gid://shopify/Product/' | append: p.id %}
<p><strong>Title:</strong> {{ p.title }}</p>
<p><strong>Properties:</strong> (Format: {variant_id: price})</p>
<p>{{ add_on_product_properties[product_gid] | json }}</p>
{% endfor %}
<p><strong>Settings</strong></p>
{{ settings | json }}
{% schema %}
{
"name": "FoxSell M&M Add Ons Test",
"settings": [],
"presets": [
{
"name": "FoxSell M&M Add Ons Test"
}
]
}
{% endschema %}
Below is a simplified example that uses the
fetch API to add a bundle to the cart. The id is the variant ID of the bundle variant and quantity is the amount of the variant that you want to add to the cart.A unique bundle identifier is generated using the bundle ID (assumed to be stored in a variable called bundleId) and the current date. This identifier is passed as a line item property, __foxsell:dynamic_add_on_bundle_id. The bundled items that need to be added are passed in the property __foxsell:dynamic_add_on_bundle_items.Copy
const currentDate = Date.now()
const identifier = `${bundleId}_${currentDate}`
let formData = {
items: [
{
id: 51594067837240, // current bundle variant id
quantity: 1,
properties: {
"__foxsell:dynamic_add_on_bundle_id": identifier,
"__foxsell:dynamic_add_on_bundle_items": [
{
"variantId": 51594057843001,
"quantity": 1,
"category": "category1", // empty for 'addOns
"type": "product", // 'product' or 'addOns'
"properties": { "_location": "warehouse1" } // optional metadata per selection
},
{
"variantId": 51594057843000,
"quantity": 1,
"type": "addOns", // 'product' or 'addOns'
"properties": { "_location": "warehouse2" } // optional metadata per selection
}
... // more items
]
}
}
]
}
fetch(window.Shopify.routes.root + 'cart/add.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => {
return response.json();
})
.catch((error) => {
console.error('Error:', error);
});
Add this snippet in your
liquid file to access bundle config via window.foxsell objectNote: The namespace and key are constant for all the storesCopy
{% liquid
assign app_namespace = 'app--67872686081'
assign dynamic_add_ons_bundle_config = product.metafields[app_namespace].dynamic_add_ons_bundle.value
assign bundle_id = dynamic_add_ons_bundle_config.bundle_id
assign options = dynamic_add_ons_bundle_config.options_v2.value
assign products = dynamic_add_ons_bundle_config.products.value
assign add_on_products = dynamic_add_ons_bundle_config.add_on_products.value
assign add_on_product_properties = dynamic_add_ons_bundle_config.add_on_product_properties.value
assign categories = dynamic_add_ons_bundle_config.categories.value
assign settings = dynamic_add_ons_bundle_config.settings.value
%}
<script>
window.foxsell = window.foxsell || {};
window.foxsell.bundleConfig = {
id: "{{ bundle_id }}",
options: {{ options | json }},
categories: {{ categories | json }},
settings: {{ settings | json }},
products: {{ products | json }},
addOnProducts: {{ add_on_products | json }},
addOnProductProperties: {
{% for product_property in add_on_product_properties %}
{% assign property_value = product_property[1] %}
'{{ product_property[0] | replace: "gid://shopify/Product/", "" }}': {
variants: {
{% for variant in property_value['variants'] %}
'{{ variant[0] | replace: "gid://shopify/ProductVariant/", ""}}': {{ variant[1] }},
{% endfor %}
}
},
{% endfor %}
}
}
</script>
Use the Shopify Storefront API to query the metafields namespace containing your bundle configuration.Note: The
namespace and key are constant for all the storesCopy
fragment Product on Product {
id
title
handle
dynamic_add_ons_bundle: metafield(
namespace: "app--67872686081"
key: "dynamic_add_ons_bundle"
) {
id
namespace
key
value
type
reference {
... on Metaobject {
id
handle
type
fields {
key
type
value
references(first: 10) {
nodes {
... on Product {
id
handle
title
}
}
}
}
}
}
}
}
Copy
interface ProductProperties {
_location?: string;
[key: string]: any;
}
interface SelectedProduct {
variantId: string;
quantity: number;
category?: string;
type: 'product' | 'addOns';
properties?: ProductProperties;
}
interface PriceConfig {
strategy: 'fixed_pricing' | 'dynamic_pricing';
value: number;
}
interface AddOnConfig {
minimum: number;
maximum: number;
}
interface OptionV2 {
title: string;
variantId: string;
quantity: number;
addOn: AddOnConfig;
additionalInfo: any[];
price: PriceConfig;
}
interface CategoryProduct {
id: string;
variants: Record<string, number>;
}
interface Category {
title: string;
quantity: number;
products: CategoryProduct[];
}
interface AddOnProductProperties {
variants: Record<string, number>;
}
interface Settings {
addOn: AddOnConfig;
price: PriceConfig;
}
interface Config {
bundleId: string;
products: string[];
categories: Category[];
optionsV2: OptionV2[];
addOnProducts: string[];
addOnProductProperties: Record<string, AddOnProductProperties>;
settings: Settings;
}
Thanks to Sid from Numbered