Dedicated to the Hydrogen framework, headless commerce, and building custom storefronts using the Storefront API.
I am setting up Buy Buttons on a WordPress website and need to display multiple collections on a single page. Even though I set up multiple elements, the different collections sporadically get mixed up into different sections. Example here: https://www.staging1.moonlightbasin.com/apparel-store/ (if everything looks fine, you may have to reload the page until you see the issue.
I am using the standard Buy Button JS embed code just altered to display multiple collections and setting iframe: false.
function ShopifyBuyInit() {
var client = ShopifyBuy.buildClient({...});
var ui = ShopifyBuy.UI.init(client);
var options = {...};
<?php for ($i=0; $i < sizeof($shopify_collections); $i++): ?> ui.createComponent('collection', { id: <?php echo $shopify_collections[$i] ?>, node: document.getElementById('collection-component-<?php echo $shopify_collections[$i] ?>'), moneyFormat: '%24%7B%7Bamount%7D%7D', options: options }); <?php endfor; ?>
}
There doesn't seem to be any rhyme or reason to when or where the additional collection products are moved. The 2nd, 3rd, 4th collections are sometimes in the right div, but sometimes are incorrectly added to the wrong div. I see the JS initializes each node correctly even when it places the products in a previous collection div.
<div id="collection-component-178746753066" class=" shopify-buy-frame shopify-buy-frame--productSet"> <div class="shopify-buy__collection"> <div class="shopify-buy__collection-products"></div> <button class="shopify-buy__collection-pagination-button shopify-buy__btn ">Next page</button> </div> </div>
Is there a trick to adding multiple collections to a single page? Is there a bug where the global "node" identifier is overwritten before all products are placed for that collection? Any help you can provide is appreciated.
I recently faced the same issue, here's how I solved it:
Since I wasn't using the buttons for the products and intended to hide it anyways, in each collection I gave the products a different text in the button that corresponds with their collection with:
"text": {
"button": "clothes"
}
Then I was able to use JavaScript to target the button's inner text and check if they match against the collection class, and if it doesn't match, then move the entire product div to the corresponding collection. I gave each collection two classes, one called 'collection' and another corresponding to its name.
<div id='collection-clothes' class="collection clothes active"></div>
<div id='collection-mugs' class="collection mugs"></div>
<div id='collection-stickers' class="collection stickers"></div>
<div id='collection-prints' class="collection prints"></div>
Here's the JavaScript for it
function fixCollectionBug() {
var collection = document.querySelectorAll('.collection');
//Within x collection, find all products
for (let i=0; i < collection.length; i++){
var products = collection[i].querySelectorAll('.shopify-buy__product');
for (let j=0; j < products.length; j++){
text = products[j].querySelector('.shopify-buy__btn').innerText
//If the product button text doesnt match the class of the collection
if (!collection[i].classList.contains(text)) {
matchProductToCollection(products[j], text);
}
}
}
function matchProductToCollection(product, text) {
// Check if each collection's class matches the text
for (let i = 0; i < collection.length; i++){
if (collection[i].classList.contains(text)){
// Select the collection element that is a parent to the product
parent = collection[i].querySelector('.shopify-buy__collection-products');
parent.appendChild(product);
}
}
};
};
You can then call this function when the collections are loaded. You could then use some CSS or JavaScript to change the button text back to what you desire. Hope this helps