JavaScript SDK
with the sparklayer sdk, you can enhance your frontend development and create more customised experiences for your users the sdk provides a range of straightforward functions to access data stored within sparklayer, as well as granting access to the graphql api and a cart update function these features empower developers to build more advanced and dynamic applications on top of the sparklayer platform example use cases the sparklayer sdk empowers developers to build more advanced and dynamic applications on top of the sparklayer platform use cases can include area details accessing data and apis provides functions to access data within sparklayer and utilize the graphql api, enabling the development of advanced and dynamic applications manual initialization allows manual initialization of the sdk, useful in headless commerce implementations customizing user experiences allows calculation of pricing data, updating the shopping cart and retrieving updated cart information, customisation of the look and feel product variant image updating custom code can be added to update product images when a variant is selected, enhancing user shopping experience by providing visual feedback custom checkout validation enables custom validation logic at checkout for personalized api calls to verify cart contents and manage checkout permissions based on custom rules (e g , managing one time discounts, product quota limits) adding custom attributes to cart items offers a method to include custom attributes with cart items, ensuring customizations are visible under the product sku and persist through to past orders please note the sparklayer sdk must not be used to modify the html and css we provide via our components within your storefront these components may be subject to update by sparklayer which may impact any changes you make, however we do ensure our sdk is always backwards compatible if you're unsure of the recommended use cases, our team will be happy to advise manual initialisation if you don't want sparklayer to initialise automatically useful in headless situations, instead of setting window\ sparkoptions you can manually call window\ initspark() once the script has loaded like so (requires at least version 1 0 21) example customisation the following code snippet illustrates how to use the sparklayer library in this example, we're using the calculatepricingforvariant function, which takes in the parent id, sku, and quantity as parameters to calculate pricing data by viewing the spark js docid\ iihkcqrrovnqfxelzeftl , you can see the functions available updating the product image when a variant is selected when using either the spark product card or spark pdp widget to select a variant, the product image is not updated by default to match the selected variant fortunately, this behavior can be easily customised using some theme code here's an example of how to accomplish this with the spark product card widget the process is virtually the same for spark pdp broadly, the following code changes are necessary add an event listener to the spark pdp or the spark product card elements for the spark variant change event within the event listener callback, show / hide product images as appropriate listen for the event when the variant selector is changed, a spark variant change event is dispatched on the spark product card element use the following code to listen for the event window\ addeventlistener("domcontentloaded", (event) => { const productcards = document queryselectorall("spark product card"); for (productcard of productcards) { productcard addeventlistener("spark variant change", (e) => { console log("spark variant change", e data) }); } }, }; please note note the event listeners can only be registered once the spark product card has been added to the page, which is why we suggest using the onready option show the product image choosing the best approach for updating variant images depends on the site's theme and markup we've tested the following process using shopify's dawn theme the first step is to ensure that all variant images are present within the document object model (dom) if you're using shopify, this can be done by iterating through product variants within the liquid template that renders the product card images you'll want to hide images for all but one variant (the first variant, which is selected by default) for the shopify dawn theme, the easiest way to do this is by setting the opacity to 0 ( style="opacity 0" ) next, add the data variant id data attribute to all variant image tags, setting it to the variant id when the user selects a variant, the following properties on the event object indicate which variant was chosen event detail product externalid platform (e g , shopify) id of the product event detail variant externalid platform (e g , shopify) id of the variant in order to display the correct image, the callback function needs to locate the image elements for the product card within the dom here's a full working example window\ sparkoptions = { onready() { const productcards = document queryselectorall("spark product card"); for (productcard of productcards) { productcard addeventlistener("spark variant change", (e) => { const cardel = e target closest(" card wrapper"); const variantid = e detail variant externalid; if (!cardel) { return; } // hide all variant images cardel queryselectorall(`img\[data variant id]`) foreach((el) => (el style opacity = "0")); // show appropriate image const variantimgel = cardel queryselector( `img\[data variant id="${variantid}"]`, ); variantimgel && (variantimgel style opacity = "1"); }); } }, }; adding custom checkout validation implementing custom checkout validation enables the client to create personalized calls to any api to verify the contents of the customer's cart and accordingly permit or restrict them from completing the checkout a potential use case could be managing one time discounts for unique customers, and utilizing an api to check if the customer has already exhausted their quota to set this up, assign an asynchronous function to the oncheckoutvalidation spark option the function must be asynchronous to prevent the user interface from being blocked while the api call is taking place this function should return an array of error objects or null if there are no errors here is an example of how this might work window\ sparkoptions = { oncheckoutvalidation async (cart) => { // do api call to validate res = await fetch("example com/cart validation", { method "post", body json stringify(cart), }); // if valid, return null if (res json() valid) { return null; } // if not valid, return array of error objects return \[ { message "unable to checkout with item due to it hit product quota ordering limits ", }, ]; }, }; in the above example, the asynchronous function oncheckoutvalidation receives a cart object as a parameter this object is then passed as a post request to the 'cart validation' endpoint of the example com api if the response from the api call is valid, the function returns null, indicating that the checkout can proceed if the response from the api call is not valid, the function returns an array of error messages, which can then be handled by your front end to alert the user that they cannot proceed with checkout " adding custom attributes to a cart item for merchants eager to offer customizations for their products, such as custom text or any other unique requirements, sparklayer introduces a flexible solution via a pre cart update hook once an item adorned with custom attributes is placed in the cart, these customizations become visible under the product sku this visibility extends to past orders, ensuring that custom attributes are consistently accessible custom attributes visible in a cart item this functionality facilitates the incorporation of custom code, allowing for seamless customization management directly from your ecommerce storefront below, we outline our recommended approach for implementing this feature step 1 setup the form fields for customisation let's imagine your store sells shirts to your b2b customers and you need to collect additional "customisations" for your products we can use the example of "shirt length" and "shirt fabric" as such customisations first, your ecommerce storefront needs to have form fields set up (e g an input field or select menu) where customers can enter their preferred shirt length this form field should be clearly labelled and placed on the product page of the customisable shirt along with the form field for "shirt length," you'll also add a select menu menu for "shirt fabric" on the product page this dropdown allows customers to select their preferred fabric from predefined options example html code for the input field shirt length shirt fabric select fabric cotton polyester cotton/polyester blend step 2 implement the precartupdatelistener function in spark options next, incorporate the precartupdatelistener function in your spark options to capture the customisation inputs when the product is added to the cart in our example above, this involves fetching the selected "shirt fabric" along with the "shirt length" and appending both as custom attributes to the product in the cart window\ sparkoptions = { precartupdatelistener (cart) => { if (!cart? products? length) { return cart; } // retrieve the customisations from their respective input fields const shirtlength = document queryselector("#shirt length")? value; const shirtfabric = document queryselector("#shirt fabric")? value; // if no customisations are provided, exit the function if (!shirtlength && !shirtfabric) { return cart; } // locate the product in the cart additions that requires customisation (e g , a specific shirt sku) const customshirtindex = cart products map((p) => p sku) indexof("shirt custom"); // if the customizable shirt is not found in the cart, exit early if (customshirtindex === 1) { return cart; } // initialize customattributes array if not already present cart products\[customshirtindex] customattributes = cart products\[customshirtindex] customattributes || \[]; // append 'shirt length' customisation, if provided if (shirtlength) { cart products\[customshirtindex] customattributes push({ key "shirt length", value shirtlength, }); } // append 'shirt fabric' customisation, if provided if (shirtfabric) { cart products\[customshirtindex] customattributes push({ key "shirt fabric", value shirtfabric, }); } // return the modified cart with the customisations included return cart; }, }; step 3 developer integration notes if you're looking to engage assistance in setting up customisations, we have some additional notes you can feedback to your developer custom input field specifications indicate the precise location on the product page for integrating custom input fields, providing clear instructions for the developers for each field, detail its intended use and the appropriate input mechanism for example, "shirt length" should be a numeric input, complete with minimum and maximum value constraints, whereas "shirt fabric" should be implemented as a select list, offering predefined options for fabric types precartupdatelistener function implementation ensure the developer understands the need to capture both of the custom inputs and append them separately as custom attributes to the cart item, using javascript similar to the above snippet testing request comprehensive testing across different scenarios to ensure the customisation feature works as intended, including edge cases where no input is provided or input is invalid line item file attachments to add a file attachment as a line item customization, you will need to do 2 things add the spark file upload field component (for selecting the file) into your website source code add some code to the precartupdatelistener in sparkoptions using the spark attachment component \<spark file upload field id="spark attachment" allowed extensions='\["png", "jpg", "jpeg"]'>\</spark file upload field> all properties property description allowed extensions a list of file extensions to allow to be uploaded (in json format) by default, this will allow most common file extensions max file size the maximum size of file that can be uploaded, in bytes max files the maximum number of files that can be uploaded required whether a file must be uploaded this component dispatches the following events spark file attachment changed when the list of files changes (i e a new file is added, or one is removed) spark file attachment failed when a file fails to upload you can add listeners for these events with the following javascript window\ addeventlistener('spark file attachment changed', (e) => { // e detail is an array of the file details in the following format // { // filesize number, // filename string, // gid string, // } // handle files }); window\ addeventlistener('spark file attachment failed', (e) => { // e detail format // { // filesize number, // filename string, // errorcode string, // } // // errorcode can be one of the following // "unsupported file type" // "file too large" // "default" // handle failed file }); example on your product page {% if customer tags contains 'b2b' %} design {% endif %} in window\ sparkoptions window\ sparkoptions = { precartupdatelistener (cart) => { if (!cart? products? length) { return cart; } // retrieve the customisations from their respective input fields const elem = document queryselector("#shirt design"); const file = elem? value; // if no customisations are provided, exit the function if (!file) { return cart; } // locate the product in the cart additions that requires customisation (e g , a specific shirt sku) const customshirtindex = cart products map((p) => p sku) indexof("shirt custom"); // if the customizable shirt is not found in the cart, exit early if (customshirtindex === 1) { return cart; } // initialize customattributes array if not already present cart products\[customshirtindex] customattributes = cart products\[customshirtindex] customattributes || \[]; // append 'custom design' customisation, if provided cart products\[customshirtindex] customattributes push({ key elem name, value file, }); // return the modified cart with the customisations included return cart; } } integrating google analytics with sparklayer sdk enabling google analytics or gtm to enable ga4 or gtm within your sparklayer setup, configure the analytics option in your sparkoptions you can specify multiple analytics providers, each with their respective event handlers and the events you wish to track window\ sparkoptions = { // other sparklayer options analytics { providers \[ { handler 'ga', // use 'ga' for google analytics events { addtocart true, cartupdate true, shoppinglistsave true, shoppinglistload true, shoppinglistdelete true, csvupload true, quickadd true, finalstagecheckout true, shippingupdate true, begincheckout true, purchase true, viewcart true } }, { handler 'gtm', // use 'gtm' for google tag manager events { addtocart true, cartupdate true, shoppinglistsave true, shoppinglistload true, shoppinglistdelete true, csvupload true, quickadd true, finalstagecheckout true, shippingupdate true, begincheckout true, purchase true, viewcart true } }, { handler function(eventname, eventparam) { console log('event fired to custom provider ', eventname, eventparam); // implement your custom analytics logic here }, events { addtocart true, cartupdate true, shoppinglistsave true, shoppinglistload true, shoppinglistdelete true, csvupload true, quickadd true, finalstagecheckout true, shippingupdate true, begincheckout true, purchase true, viewcart true } } ] } }; configuration details providers an array of analytics providers you wish to integrate each provider object can define a handler and the specific events to track provider options provider type description 'ga' integrates with google analytics (ga4) this works best when using shopify's ga4 solution https //help shopify com/en/manual/reports and analytics/google analytics/google analytics setup 'gtm' integrates with google tag manager function allows for a custom analytics handler use this to integrate with other analytics platforms or to implement bespoke tracking logic available events event name description addtocart triggered when a product is added to the cart cartupdate fired when the cart is updated (e g , quantity changes, item removals) shoppinglistsave occurs when a shopping list is saved shoppinglistload occurs when a shopping list is loaded shoppinglistdelete occurs when a shopping list is deleted csvupload triggered when a csv file is uploaded quickadd fired during quick add actions finalstagecheckout occurs at the final stage of the checkout process shippingupdate fired when shipping details are updated during the checkout begincheckout triggered when the checkout process begins purchase occurs upon successful purchase completion viewcart fired when the cart is viewed custom analytics provider if you need to integrate with an analytics service not natively supported by sparklayer, you can define a custom handler function this function receives the event name and parameters, allowing you to implement any tracking logic as needed { handler function(eventname, eventparam) { // example send event data to a custom analytics service fetch('https //your analytics endpoint com/track', { method 'post', headers { 'content type' 'application/json' }, body json stringify({ event eventname, parameters eventparam }) }) then(response => response json()) then(data => { console log('custom analytics event tracked ', data); }) catch(error => { console error('error tracking custom analytics event ', error); }); }, events { addtocart true, cartupdate true, // other events } } configuring redirect on login to configure redirection within sparklayer, you need to include the spark redirect js script in your html this script should be placed outside of the {% if customer metafields sparklayer authentication %} conditional block in order for it to be picked up even if the user isn't authenticated by default, if a user is not authenticated, they will be redirected to the /account/login page you can customize this login path by setting the window\ sparkredirectloginpath variable before including the script some links (for example, the 'view order' button in certain emails) will trigger specific functionality on sparklayer once the user has logged in in order for this to work, you need to add the spark redirect js script above in addition to the core spark script