Side Cart
What is a Side Cart?
A side cart (also called a drawer cart or slide cart) is a cart that can be viewed and modified by the customer from any page on the site, allowing the user to make changes to their cart without interrupting the purchase journey flow.
Prerequisites
- Listed Shopify app is installed
- Shipping Protection has been approved and enabled for the store
- Existing merchant with warranty offers on the site
Getting Started
You will need to navigate into your Shopify Store's backend to access the liquid files where you will make the changes listed below.
- Go to the Shopify Script Editor.
- Create a duplicate of your Current Theme :
We strongly advise working in a separate, non-live copy of your theme, to ensure your changes aren't visible to customer until you are ready to publish them.- Select the theme you'd like to use, then click Actions -> Duplicate
Under the duplicate of the theme, usually labelledCopy of {live_theme_name}
click Actions -> Rename - Replace
Copy of
withExtend -
- Click Actions -> Edit Code
- Select the theme you'd like to use, then click Actions -> Duplicate
You will want to use this newly Copied theme to integrate the code changes below.
Code Integration
-
Add this render to the bottom of your 'extend-configuration.liquid' file:
<!-- Extend -- Load side cart integration script --> {% render 'extend-side-cart-integration' %} <!-- Extend -- End Extend code -->
-
Create a new file in the snippets folder and name it
extend-side-cart-integration.liquid
-
Add this code to the contents of this new file:
<script> // Run scripts on DOMContentLoaded to avoid affecting site load time window.addEventListener('DOMContentLoaded', function () { // Only run ajax integration if Extend and ExtendShopify is defined, and the currency is set to USD if (window.Extend && window.ExtendShopify && window.Shopify && window.Shopify.currency && window.Shopify.currency.active === 'USD') { /***********************/ /* Variables to Change */ /***********************/ // Example of a selector : // let shippingOfferLocation = '#mini-cart .mini-cart__drawer-footer' // For help grabbing a CSS selector, use the document located here: // https://helloextend.atlassian.net/l/cp/1djs2knw // DO NOT CHANGE ANY CODE ABOVE THIS LINE // Replace the value in quotations with: Selector for side cart location where Shipping Offer should go, typically the footer or bottom of the side cart let shippingOfferLocation = '' // Replace the value in quotations with: Selector for side cart toggle button let cartToggle = '' // Replace the value in quotations with: Selector for side cart increase quantity buttons let quantityUp = '' // Replace the value in quotations with: Selector for side cart decrease quantity buttons let quantityDown = '' // Replace the value in quotations with: Selector for side cart remove buttons let removeButton = '' // Troubleshooting: Set to change the word 'false' to 'true' to begin troubleshooting // When finished, change 'true' back to 'false' (with no quotations) let troubleShooter = false; // DO NOT CHANGE ANY CODE BELOW THIS LINE /******************/ /* Util Functions */ /******************/ // findAll(element) - querySelectorAll to search for children in document OR a parentElement function findAll(elementToFind, parentElement) { const items = parentElement ? parentElement.querySelectorAll(elementToFind) : document.querySelectorAll(elementToFind); return items; } function extendTroubleShooter() { let objectToLog = { "shippingOfferLocation": shippingOfferLocation ? document.querySelector(shippingOfferLocation) : 'None Specified', "cartToggle": cartToggle ? document.querySelector(cartToggle) : 'None Specified', "quantityUp": quantityUp ? document.querySelector(quantityUp) : 'None Specified', "quantityDown": quantityDown ? document.querySelector(quantityDown) : 'None Specified', "removeButton": removeButton ? document.querySelector(removeButton) : 'None Specified' } function returnSelector() { let returnString = ''; Object.keys(objectToLog).forEach(function (each, index) { if (Object.values(objectToLog)[index] === 'None Specified') { returnString = returnString + `\n• No element was specified for ${each}.\n` } else { returnString = returnString + `\n• The element found for ${each}:\n` + 'Tag Name: ' + Object.values(objectToLog)[index].nodeName + '\nID: ' + Object.values(objectToLog)[index].id + '\nClass List: ' + Object.values(objectToLog)[index].classList + '\n' } }) return returnString } alert("Hello, here is your Extend troubleshoot message.\nRemember to set troubleShooter back to false before pushing this theme live!\nThis message can also be viewed in the console.\n" + returnSelector()) console.log("Hello, here is the console portion of your Extend troubleshoot message.\nRemember to set troubleShooter back to false before pushing this theme live!\n" + returnSelector()) } /***********************/ /* Shipping Protection */ /***********************/ const shippingProtectionOfferId = 'extend-drawer-shipping-offer' // This is the ID that will be assigned to the Extend Shipping Protection Offer function renderOrUpdateSP(spcart) { const mappedCartItems = ExtendShopify.spCartMapper(spcart.items) if (document.querySelector('#extend-drawer-shipping-offer') && document.querySelector('#extend-drawer-shipping-offer div')) { document.querySelector('#extend-drawer-shipping-offer div').remove() } const shippingProtectionOffer = document.createElement('div') shippingProtectionOffer.id = shippingProtectionOfferId; if (document.querySelector(shippingOfferLocation)) document.querySelector(shippingOfferLocation).prepend(shippingProtectionOffer) const isShippingProtectionInCart = ExtendShopify.shippingProtectionInCart(spcart.items); if (window.location.href.indexOf("cart") === -1) { Extend.shippingProtection.destroy() } Extend.shippingProtection.render({ selector: '#extend-drawer-shipping-offer', items: mappedCartItems, isShippingProtectionInCart, onEnable(quote) { ExtendShopify.addSpPlanToCart({ quote, callback(err, resp) { if (err) { return; } else window.location.reload(); }, }) }, onDisable(quote) { ExtendShopify.updateSpPlanInCart({ action: 'remove', quote, callback(err, resp) { // an error occurred if (err) { return; } else if (resp.isUpdated) window.location.reload(); }, }) }, onUpdate(quote) { ExtendShopify.updateSpPlanInCart({ action: 'update', quote, callback(err, resp) { // an error occurred if (err) { return; } else if (resp.isUpdated) window.location.reload(); }, }) }, }); } // initializeCartOffer should be the called at the very top of initializeCartOffers() function initializeCartOffer() { ExtendShopify.updateExtendLineItems({ balanceCart: true, callback(err, data) { if (!err && data && (data.updates || data.additions)) { window.location.reload() } renderOrUpdateSP(data.cart) }, }) } if (troubleShooter) { window.setTimeout(function () { extendTroubleShooter() }, 1000) } /*******************************/ /* Cart Change Detection Start */ /*******************************/ var cartChangeListeners = function (e) { var el = e.target if ((cartToggle && document.querySelector(cartToggle) && el.matches(cartToggle)) || (quantityUp && document.querySelector(quantityUp) && el.matches(quantityUp)) || (quantityDown && document.querySelector(quantityDown) && el.matches(quantityDown)) || (removeButton && document.querySelector(removeButton) && el.matches(removeButton))) { window.setTimeout(function () { initializeCartOffer(); }, 1000) } } //Adds event listener with event delegation to listen for button click document.addEventListener('click', cartChangeListeners, true); } }); </script> <style> #extend-drawer-shipping-offer { text-align: center !important; height: 120px !important; } .extend-warranty-info { font-size: 13px; color: #424242B3; } #sp-learn-more-modal-iframe { z-index: 9999999999 !important; } </style>
-
In the section between lines 21 - 33, insert the 5 necessary CSS selectors to complete this integration. Those selectors are for the following:
shippingOfferLocation
- Location where the shipping offer will be insertedcartToggle
- Element that must be clicked to open the side cartquantityUp
(If applicable) - Button on each product to increase its quantityquantityDown
(If applicable) - Button on each product to decrease its quantityremoveButton
(If applicable) - Button on each product to remove it from the cart
Please use this guide on how to get an CSS selector if additional context is needed.
You should not modify any code outside of lines 21 - 38
Below are some general appearance examples for these locations. Keep in mind that they may differ in appearance, and some side carts may not even feature product removal and quantity change options. In these cases, simply ignore the lines requesting those selectors.
Troubleshooting
There is a troubleshooting tool built into the snippet.
To use it simply change the word false to true on line 38.
Remember to change this back to false before publishing the theme!
The tool will display information about which Elements are being grabbed with the CSS Selectors you have added.
If you run into any issues during this integration process or have questions please reach out to our team through your Merchant Portal.
Updated about 2 months ago