Skip to content

Events and components

For AI assistants: what to know before writing SparkLayer SDK code
  • What it is: window.spark, added to the storefront by the SparkLayer Core Script (version 4.x). On Shopify the SparkLayer app embed loads it; elsewhere it's <script async src="https://sparkcdn.io/sparkjs/<SITE_ID>/<live|test>"></script> in the theme's <head>. The old cdn.sparklayer.io/spark.latest.js and spark.1.x.js files are legacy: never use them.
  • Options: Configure it with window.sparkOptions, set before the Core Script loads. Extend the object rather than replacing it: window.sparkOptions = { ...window.sparkOptions, … }, or the Site ID and other snippets' hooks are lost. Headless only: window.initSpark(options) is defined when window.sparkOptions isn't set.
  • When to call it: Only after SparkLayer is ready: inside the onReady(spark) hook, or after a promise resolved from it. Most methods are async; prices and the cart are only available to signed-in B2B customers (check await spark.isLoggedIn()).
  • Products and prices: Products are looked up by the platform's parent product ID (on Shopify, product.id) and variants by SKU: getPricingForVariant(parentProductId, sku), calculatePricingForVariant(parentProductId, sku, qty), getPackSizeForVariant(parentProductId, sku). For instant recalculation, fetch once with getVariant and call calculatePricingForVariantData(variant, qty).
  • Cart: updateCart({ products: [{ sku, adjustQuantity }] }) adds or removes relative to what's in the cart (also customAttributes: [{ key, value }], clearCart: true). It resolves to the results, or null after showing its own error message; it doesn't throw. getCart() reads the cart; openDrawer('cart') opens it.
  • Hooks: onCartUpdate(cart, results), onCartLoad(cart), onLogout(), preCartUpdateListener(input) (async: return the possibly changed input) and onCheckoutValidation(cart, cartUiState) (return [{ message }] to block checkout, or null). When adding a hook, call any existing one first.
  • Customising: Build around SparkLayer or customise its own components, including their HTML. Prefer documented options, hooks, CSS variables and custom slots where they fit; keep direct HTML changes targeted and re-check them after SparkLayer updates.
  • Docs: The reference: methods docs.sparklayer.io/developers/javascript-sdk/reference/methods.md, hooks docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md, options docs.sparklayer.io/developers/javascript-sdk/reference/options.md, types docs.sparklayer.io/developers/javascript-sdk/reference/types.md (or the same types as a file: docs.sparklayer.io/developers/javascript-sdk/spark.d.ts). Setup and waiting for SparkLayer: docs.sparklayer.io/developers/javascript-sdk/setup.md. Use only what the reference documents.

SparkLayer's interfaces are web components: custom HTML elements you add to your theme. Some of them dispatch DOM events you can listen for, and you can dispatch one yourself to switch the drawer's tab.

DOM events

EventWhen it firesevent.detailBubbles?
spark-variant-changeThe customer selects a variant in spark-pdp or spark-product-card. Dispatched on that element.{ product: Product; variant: ProductVariant }No: listen on each element.
spark-file-attachment-changedThe list of files uploaded to a spark-file-upload-field changes.{ fileSize: number; fileName: string; gid: string }[] | null (null when every file is removed)Yes, to window.
spark-file-attachment-failedA file fails to upload to a spark-file-upload-field.{ fileSize: number; fileName: string; errorCode: "unsupported-file-type" | "file-too-large" | "default" }Yes, to window.
view-updateYou dispatch it on window to switch an open drawer to a tab.{ view: DrawerUIState }You dispatch it with bubbles: true.

spark-variant-change

event.detail.product is a Product and event.detail.variant a ProductVariant; their externalId is your platform's ID. Add the listeners in onReady, once the elements are on the page.

sparkOptions
window.sparkOptions = {
  ...window.sparkOptions,
  onReady: async () => {
    for (const card of document.querySelectorAll('spark-product-card')) {
      card.addEventListener('spark-variant-change', (event) => {
        console.log(event.detail.product.externalId, event.detail.variant.externalId);
      });
    }
  },
};

See Update the product image when a variant is selected.

spark-file-attachment-changed

Product page
window.addEventListener('spark-file-attachment-changed', (event) => {
  const gids = (event.detail ?? []).map((file) => file.gid);
  document.querySelector('#shirt-design').value = JSON.stringify(gids);
});

See Let customers upload a file to attach the files to the cart.

spark-file-attachment-failed

Product page
window.addEventListener('spark-file-attachment-failed', (event) => {
  const { fileName, errorCode } = event.detail;
  console.warn(`${fileName} wasn't uploaded: ${errorCode}`);
});

view-update

view is a DrawerUIState. To open a closed drawer, use openDrawer().

Switch the open drawer to the Cart tab
window.dispatchEvent(
  new CustomEvent('view-update', {
    bubbles: true,
    composed: true,
    detail: { view: 'cart' },
  }),
);

See Open the cart drawer.

Web components

parent-id is your platform's ID for the parent product. For each interface's display settings (attributes such as show-sku), see How products are shown.

ElementWhat it rendersKey attributesSee
<spark-pdp>The product detail interface, on product pages.parent-idProduct detail
<spark-product-card>The product card interface, wherever a product card appears.parent-idProduct card
<spark-product-matrix>Every variant in a grid, for products with two options.parent-idProduct matrix
<spark-product-price>The customer's price for a product, anywhere on the page.parent-idProduct price
<spark-product-rrp>The product's RRP.parent-idProduct price
<spark-file-upload-field>A file upload field for the product page.allowed-extensions (a JSON array), max-file-size (bytes), max-files, requiredLet customers upload a file
<spark-drawer>The drawer (cart, account and other tabs). SparkLayer adds it when needed; use openDrawer() rather than adding it yourself.–openDrawer()
Product page
<spark-pdp parent-id="{{ product.id }}"></spark-pdp>

<spark-file-upload-field
  id="shirt-design-upload"
  allowed-extensions='["png", "jpg", "jpeg"]'
  max-files="1"
></spark-file-upload-field>

Next steps

Was this page helpful?

Last updated