Types
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 oldcdn.sparklayer.io/spark.latest.jsandspark.1.x.jsfiles 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 whenwindow.sparkOptionsisn'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 (checkawait 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 withgetVariantand callcalculatePricingForVariantData(variant, qty). - Cart:
updateCart({ products: [{ sku, adjustQuantity }] })adds or removes relative to what's in the cart (alsocustomAttributes: [{ key, value }],clearCart: true). It resolves to the results, ornullafter 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) andonCheckoutValidation(cart, cartUiState)(return[{ message }]to block checkout, ornull). 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.
The objects you pass to the SDK and get back from it, written in TypeScript and listed A to Z. In JavaScript, they describe the shape of those objects. Every block on this page goes into spark.d.ts, which you can download for autocomplete and type checking in your editor.
The cart, product and pricing types come from SparkLayer's GraphQL API. Their field types and nullability are inferred from how the SDK uses them, so treat a field as possibly null unless you're sure it's set.
AccountSectionId
The sections of the My Account panel, used in display.sectionConfiguration to reorder or hide them.
type AccountSectionId =
| "spark-slot-my-account"
| "recent-activity"
| "shopping-lists"
| "favourites"
| "financials"
| "my-details"
| "reports"
| "address-book"
| "company-users";Used by: DisplayOptions
AnalyticsEventName
The B2B events SparkLayer can send to your analytics. See Event tracking for analytics for what each event means.
type AnalyticsEventName =
| "addToCart"
| "cartUpdate"
| "shoppingListSave"
| "shoppingListLoad"
| "shoppingListDelete"
| "csvUpload"
| "quickAdd"
| "finalStageCheckout"
| "shippingUpdate"
| "beginCheckout"
| "purchase"
| "viewCart";Used by: AnalyticsOptions
AnalyticsOptions
The type of the analytics option: the providers to send events to, and which events each one gets. See Event tracking for analytics.
type AnalyticsOptions = {
providers: {
// "ga" for Google Analytics (GA4), "gtm" for Google Tag Manager, or your own function
handler: "ga" | "gtm" | ((eventName: AnalyticsEventName, eventParams: unknown) => void);
// The events to send to this provider
events: Partial<Record<AnalyticsEventName, boolean>>;
}[];
};Used by: the analytics option
Cart
The B2B cart.
type Cart = {
cartUuid: string;
intent: string; // For example "ORDER"
canCreateOrder: boolean;
canCreateQuote: boolean;
hasLaunched: boolean;
lockedByUserId: string | null;
lockedByUserLastAccessedAt: string | null;
loadedFromPurchaseAt: string | null;
loadedFromPurchaseType: string | null;
items: CartItem[];
validationErrors: CartValidationError[];
taxInclusiveDisplay: boolean;
totals: CartTotals;
currencyCode: string;
totalWeight: number | null;
customerAddresses: { id: string; description: string }[];
deliveryAddressId: string | null;
customerReference: string | null;
poNumber: string | null;
shippingRequestedDate: string | null;
customFields: { name: string; value: string }[];
approvingFor: { name: string } | null;
discounts: {
id: string;
slug: string;
name: string;
appliedCouponCodes: string[];
amount: { net: number; gross: number; currencyCode: string };
}[];
discountsAreAvailable: boolean;
couponCodes: string[];
removedCouponCodes: string[];
quote: {
statusSlug: string;
statusUpdated: string;
expiry: string | null;
assignedAgent: { id: string } | null;
message: string | null;
note: string | null;
} | null;
};Used by: getCart(), getCartCache(), addCustomLineItem(), onCartLoad, onCartUpdate, onCheckoutValidation
CartItem
One line in the cart. It has every ProductVariant field (sku, name, price and so on) plus these:
type CartItem = ProductVariant & {
type: string;
itemKey: string; // Identifies the line in updateCart
quantity: number;
customAttributes: { key: string; value: string; type?: string | null }[];
lineTotal: CartLineAmount;
lineTotalPreDiscounts: CartLineAmount;
lineTotalDiscountAmount: CartLineAmount;
unitTotal: CartLineAmount;
unitTotalPreDiscounts: CartLineAmount;
unitTotalDiscountAmount: CartLineAmount;
quotedPrice: string | null;
preorderQuantityDisplay: number | null;
};Used by: Cart (items), calculatePricingForVariantData()
CartItemInput
One product in an UpdateCart. Identify the line by sku or itemKey, and set the quantity with adjustQuantity (added to the current quantity; negative to remove) or quantity (the exact quantity; 0 removes the line).
type CartItemInput = {
sku?: string;
itemKey?: string; // From a CartItem
adjustQuantity?: number;
quantity?: number;
customAttributes?: { key: string; value: string; type?: string }[];
};For a file, value is a JSON string of an array of file GIDs from uploadFile().
Used by: UpdateCart (products)
CartLineAmount
An amount on a cart line, such as its total or unit price.
type CartLineAmount = {
net: number;
gross: number;
currencyCode: string;
taxInclusiveDisplay: boolean;
};Used by: CartItem
CartMoney
An amount in the cart's totals.
type CartMoney = { number: string };Used by: CartTotals
CartResults
The result for one product line in an updateCart call. See What updateCart returns for the messages types.
type CartResults = {
messages: { type: string }[];
requestedQuantity: number;
resultantQuantity: number;
itemKey: string;
sku: string;
name: string;
};Used by: updateCart(), onCartUpdate
CartTotals
The cart's totals. Each amount is a CartMoney object with a number.
type CartTotals = {
subTotal: {
preDiscount: { net: CartMoney; gross: CartMoney };
discount: { net: CartMoney; gross: CartMoney };
charge: { net: CartMoney; gross: CartMoney };
};
shipping: {
preDiscount: { net: CartMoney };
discount: { net: CartMoney };
charge: { net: CartMoney };
};
total: {
charge: { gross: CartMoney; tax: CartMoney };
discount: { net: CartMoney };
preDiscount: { gross: CartMoney };
};
};Used by: Cart (totals)
CartUIState
The current checkout step.
type CartUIState = "cart" | "shipping" | "quote-details" | "payment" | "thanks";Used by: onCheckoutValidation
CartValidationError
A reason the cart can't be checked out yet, such as an order minimum that hasn't been met. Each error has a type code (for example quantity-unavailable or pricing-unavailable) and the fields for its kind.
The type is one of the cart validation codes the API uses: maximum-order-item-quantity, maximum-order-totals, maximum-parent-quantity, maximum-variant-quantity, minimum-order-item-quantity, minimum-order-totals, minimum-parent-quantity, minimum-variant-quantity, pack-size, pricing-unavailable, pricing-unavailable-for-selected-qty or quantity-unavailable.
type CartValidationError = {
type: string;
amount?: number;
amountGross?: number;
minimum?: number;
maximum?: number;
productName?: string;
parentSKU?: string;
variantSKU?: string;
packSize?: number;
availableQuantity?: number;
overridden?: boolean;
};| Kind of error (GraphQL type) | Fields |
|---|---|
CartValidationErrorMinimumOrderTotals, CartValidationErrorMaximumOrderTotals | amount, amountGross |
CartValidationErrorMinimumOrderItemQuantity | minimum |
CartValidationErrorMaximumOrderItemQuantity | maximum |
CartValidationErrorMinimumParentQuantity, CartValidationErrorMaximumParentQuantity | minimum or maximum, productName, parentSKU, overridden |
CartValidationErrorMinimumVariantQuantity, CartValidationErrorMaximumVariantQuantity | minimum or maximum, variantSKU, overridden |
CartValidationErrorPackSize | packSize, variantSKU, overridden |
CartValidationErrorQuantityUnavailable | variantSKU, availableQuantity |
CartValidationErrorPricingUnavailable, CartValidationErrorPricingUnavailableForSelectedQty | variantSKU |
Used by: Cart (validationErrors)
CheckoutElementConfig
One entry in checkoutCustomElements: a standard field by id, or a custom field by name. See Custom field settings for every key and Standard checkout fields for the IDs.
type CheckoutElementConfig = {
// A standard field
id?: "customer-reference" | "po-number" | "shipping-requested-date";
// A custom field (required unless id is set)
name?: string;
// Customer-facing text, keyed by language code
translations?: Record<string, { title: string; detail?: string; [messageKey: string]: string | undefined }>;
// HTML attributes such as type, required, min, max, maxlength and pattern
attributes?: Record<string, string | number | boolean>;
// For select fields: the drop-down options, optionally in groups
options?: {
translations?: Record<string, { groupName: string }>;
items: { value: string; translations: Record<string, { label: string }> }[];
}[];
// Returns a message key from translations if the value is invalid
onChange?(value: string, element: HTMLElement): string | null | undefined;
};Used by: the checkoutCustomElements option
CustomAccountDetailLinkType
Formats a customAccountDetails value as a link of this kind.
type CustomAccountDetailLinkType = "email" | "phone" | "sms" | "website";Used by: the customAccountDetails option
CustomLineItemInput
A custom line item: a free-text name, price and quantity not tied to a SKU.
type CustomLineItemInput = {
// The name shown on the custom line item
name: string;
// The price of a single unit, as a decimal string
quotedPrice: string;
quantity: number;
};Used by: addCustomLineItem()
DisplayOptions
The type of the display option.
type DisplayOptions = {
orderListShowShippingAddress: boolean;
customerReferenceHidden: boolean; // deprecated
customerReferenceRequired: boolean; // deprecated
customerReferenceMaxLength?: number; // deprecated
darkTheme: boolean;
savingsUseRrp: boolean;
roundPriceBreakPercentages: boolean;
showPriceBreakSavings: boolean;
sectionConfiguration: {
"my-account"?: {
order?: AccountSectionId[];
hide?: AccountSectionId[];
};
};
showSlots: string[];
showRrpToggle: boolean;
showFavouritesLists: boolean;
showShoppingLists: boolean;
showSkus: boolean;
hideFinancials?: boolean;
};| Property | Default | What it does |
|---|---|---|
sectionConfiguration | {} | Reorder (order) or hide (hide) My Account sections by AccountSectionId. See My account. |
showSlots | [] | Custom slots to show. See Custom slots. |
showFavouritesLists | true | Whether to show the favourites lists feature. |
showShoppingLists | true | Whether to show the shopping lists feature. |
showSkus | true | Whether to show product SKUs on cart line items. |
darkTheme | false | Use the dark theme. See Customising design. |
savingsUseRrp | false | Calculate savings against the RRP. |
roundPriceBreakPercentages | true | Round price break percentages. |
showPriceBreakSavings | true | Show savings on price breaks. |
showRrpToggle | false | Show the RRP toggle. |
orderListShowShippingAddress | false | Show the shipping address in the purchases list. |
hideFinancials? | – | Hide the Financials section of My Account. |
customerReferenceHidden, customerReferenceRequired, customerReferenceMaxLength? | false, false, – | Deprecated. Use a { id: 'customer-reference' } entry in checkoutCustomElements instead. |
Used by: the display option
DrawerUIState
A tab of the SparkLayer drawer.
type DrawerUIState = "dashboard" | "browse-catalog" | "cart" | "sales-agent" | "account";Used by: openDrawer(), the view-update event
ErrorOf
The error type of a GraphQL query or mutation passed to fetch. For a plain query string, it's GraphqlError.
type ErrorOf<Q> = Q extends { readonly __graphqlTypes?: { error: infer TError } }
? TError
: GraphqlError;Used by: fetch()
FetchResponse
The response returned by fetch: a standard Response whose json() resolves to the GraphQL response.
interface FetchResponse<TData = unknown, TError = GraphqlError> extends Response {
json(): Promise<{ data: TData; errors: TError[] }>;
}Used by: fetch()
GraphqlError
An entry in the errors array of a GraphQL response.
type GraphqlError = {
message: string;
path?: (string | number)[];
extensions?: { code?: string; [key: string]: unknown };
};Used by: FetchResponse, fetch()
GraphqlExtensionError
A GraphqlError with a code in extensions that identifies the error.
type GraphqlExtensionError = GraphqlError & {
extensions: { code: string; [key: string]: unknown };
};Used by: fetch()
GraphqlQueryOrMutation
The query you pass to fetch. In JavaScript, pass it as a string, and the variables as a plain object. In TypeScript, a typed query can also carry its response, variables and error types, which ResponseOf, VariablesOf and ErrorOf read back.
type GraphqlQueryOrMutation<
TResponse = unknown,
TVariables = Record<string, unknown>,
TError = GraphqlError,
> = string & {
// Type-only: never set at runtime
readonly __graphqlTypes?: { response: TResponse; variables: TVariables; error: TError };
};Used by: fetch()
PaymentMethodName
The payment methods you can list in paymentMethodsOrder.
type PaymentMethodName = "paymentOnAccount" | "paymentByInvoice" | "upfrontPayment" | "quote";Used by: the paymentMethodsOrder option
Product
A product, with its variants.
type Product = {
id: string;
externalId: string; // Your platform's product ID
slug: string;
variants: ProductVariant[];
};Used by: getProduct(), getProductBySlug(), the spark-variant-change event
ProductVariant
One variant of a product, and the base of each CartItem.
type ProductVariant = {
id: string;
externalId: string; // Your platform's variant ID
parentExternalId: string; // Your platform's product ID
stockDisplay: {
status: string; // For example "out_of_stock" or "backorder"
units: number | null;
available: unknown;
} | null;
restockDate: string | null;
cartImageUrl: string | null;
position: number;
sku: string;
barcode: string | null;
slug: string;
name: string;
price: VariantPrice | null;
rrp: unknown; // Legacy: use rrpV2
rrpV2: { number: string; currency: string } | null;
priceBreaks: VariantPriceBreak[];
// Product settings, such as packSize, minOrderQuantity and maxOrderQuantity
settings: { key: string; value: unknown }[];
// The variant's options, such as { group: "Size", value: "M" }
options: { group: string; value: string }[];
};Used by: getVariant(), Product (variants), CartItem, calculatePricingForVariantData(), the spark-variant-change event
ProductVariantDataPricing
The variant data calculatePricingForVariantData needs. A ProductVariant or CartItem has these fields.
type ProductVariantDataPricing = {
priceBreaks: VariantPriceBreak[] | null;
rrpV2?: { number: string; currency: string } | null;
unitTotal?: { currencyCode: string } | null; // Cart items only
};Used by: calculatePricingForVariantData()
ProductVariantPricing
The price for a quantity of a variant: the total, the unit price at that quantity and the price breaks.
type ProductVariantPricing = {
totalPrice: number | null; // unitPrice × quantity
totalRrpPrice: number | null;
hasPriceBreaks: boolean;
unitPrice: number | null; // The unit price at this quantity
basePrice: number | null; // The unit price before price breaks
priceBreaks: VariantPriceBreak[];
priceBreakSavingsPercentage: number | null;
rrpV2: { number: string; currency: string } | null;
currencyCode: string;
unitPriceBreakdown: {
items: {
unitOfMeasure: string | null;
price: number;
quantity: number;
uomQuantity: number;
}[];
};
};Used by: calculatePricingForVariant(), calculatePricingForVariantData()
ResponseOf
The data type of a GraphQL query or mutation passed to fetch. For a plain query string, it's unknown.
type ResponseOf<Q> = Q extends { readonly __graphqlTypes?: { response: infer TResponse } }
? TResponse
: unknown;Used by: fetch()
SimplifiedProductPrice
The "from" price across a product's variants, and how many different prices there are.
type SimplifiedProductPrice = {
numberOfPrices: number;
numberOfPricesExcludingBreaks: number;
numberOfRrpPrices: number;
fromPrice: number | null;
fromPriceExcludingBreaks: number | null;
currencyCode: string;
hasPriceBreaks: boolean;
rrpPrice: number | null;
rrpCurrencyCode: string | null;
taxInclusiveDisplay: boolean;
};If numberOfPrices is more than 1, show "from" before fromPrice.
Used by: getPriceForProduct()
Spark
The window.spark object. See Methods for each one.
type Spark = {
options: SparkLayerOptions;
isLoggedIn(): Promise<boolean>;
switchImpersonatingCustomer(customerId: string | null): Promise<UserData | null>;
refreshGlobalData(): Promise<UserData | null>;
getActiveCustomerVerificationToken(): Promise<string | null>;
setActiveCompanySection(sectionId: string): Promise<boolean>;
getProduct(parentProductId: string): Promise<Product>;
getProductBySlug(slug: string): Promise<Product>;
getVariant(parentProductId: string, variantSku: string): Promise<ProductVariant>;
getPriceForProduct(parentProductId: string): Promise<SimplifiedProductPrice>;
getPricingForVariant(
parentProductId: string,
variantSku: string,
): Promise<{
price: number | null;
rrp: number | null;
rrpCurrencyCode: string | null;
priceBreaks: VariantPriceBreak[];
currencyCode: string;
}>;
getRrpPriceForVariant(
parentProductId: string,
variantSku: string,
): Promise<{ rrp: number | null; currencyCode: string | null }>;
getPackSizeForVariant(parentProductId: string, variantSku: string): Promise<number>;
calculatePricingForVariant(
parentProductId: string,
variantSku: string,
qty: number,
qtyAcrossVariants?: number | null,
): Promise<ProductVariantPricing>;
calculatePricingForVariantData(
variant: ProductVariantDataPricing,
qty: number,
qtyAcrossVariants?: number | null,
): ProductVariantPricing;
getCart(): Promise<Cart | null>;
getCartCache(): Cart | null;
updateCart(
input: Partial<UpdateCart>,
cartSuccessHandledLocally?: boolean,
cartErrorsHandledLocally?: boolean,
): Promise<CartResults[] | null>;
addCustomLineItem(customItem: CustomLineItemInput): Promise<Cart | null>;
externalClearBasket(): Promise<void>;
openDrawer(initialTab?: DrawerUIState): void;
closeDrawer(): void;
uploadFile(fileName: string, fileData: Blob): Promise<string>;
fetch<Q extends GraphqlQueryOrMutation<unknown, Record<string, unknown>, GraphqlError | GraphqlExtensionError>>(
query: Q,
variables?: VariablesOf<Q>,
useImpersonatingCustomer?: boolean,
bypassAppProxy?: boolean,
signal?: AbortSignal,
): Promise<FetchResponse<ResponseOf<Q>, ErrorOf<Q>>>;
};Used by: window.spark, window.initSpark(), onReady, onLoad
SparkLayerOptions
The type of window.sparkOptions and the options you pass to window.initSpark(). See Options and Hooks for each one.
type SparkLayerOptions = {
sparkDomain: "app.sparklayer.io" | "test.app.sparklayer.io";
platform: "base" | "bigcommerce" | "shopify" | "wix" | "woocommerce" | "magento";
siteId: string;
rootUrl: string;
accountRedirect: {
urlRegex?: RegExp;
goTo?: string;
};
cartRedirect: {
urlRegex?: RegExp;
goTo?: string;
};
wordpressSiteUrl?: string;
accountButtonSelectors: string;
logoutButtonSelectors: string;
cartButtonSelectors: string;
loginButtonSelectors: string;
display: DisplayOptions;
termsAndConditionsLink: string;
language: string;
locale: string | null;
translations: Translations;
showTranslations: boolean;
checkoutCustomElements: CheckoutElementConfig[];
paymentMethodsOrder: PaymentMethodName[];
saveToAddressBookDefault: boolean;
productLink: string;
customAccountDetails: {
title: string;
value: string | number;
displayText?: string;
type?: CustomAccountDetailLinkType;
}[];
onCheckoutValidation(
cart: Cart,
cartUiState: CartUIState,
): Promise<{ message: string }[] | null>;
onCartUpdate(cart: Cart, results: CartResults[]): Promise<void>;
onCartLoad(cart: Cart): Promise<void>;
preCartUpdateListener(input: Partial<UpdateCart>): Promise<Partial<UpdateCart>>;
onReady?(spark: Spark): Promise<void>;
onLoad?(spark: Spark): Promise<void>;
onLogout?(): Promise<void>;
shopify?: {
useAppProxy?: boolean;
};
bigcommerce?: {
appClientId?: string;
};
auth: {
user?: string;
token?: string;
};
authLogoutUri: string | null;
analytics?: AnalyticsOptions;
igniteCheckoutContext?: Record<string, unknown>;
};Used by: window.sparkOptions, window.initSpark(), Spark (options)
Translations
The type of the translations option: text overrides keyed by language code, then by translation key. See Change text in the Core Script.
type Translations = Record<string, Record<string, string>>;Used by: the translations option
UpdateCart
A change to the cart. Every field is optional: send only what you want to change. See Cart.
type UpdateCart = {
clearCart?: boolean;
products?: CartItemInput[];
deliveryAddressId?: string;
customerReference?: string;
poNumber?: string;
shippingRequestedDate?: string;
customFields?: { name: string; value: string }[];
cartIntent?: string;
};SparkLayer adds the impersonated customer and company section for you.
Used by: updateCart(), preCartUpdateListener
UserData
The active customer. This lists the fields most integrations need; the object has more.
type UserData = {
id: string;
email: string;
name: string;
companyName: string | null;
customerVerificationToken: string | null;
salesAgent: boolean;
parentAccount: { id: string; name: string; email: string } | null;
companySections: { id: string; name: string }[];
};Used by: switchImpersonatingCustomer(), refreshGlobalData()
VariablesOf
The variables type of a GraphQL query or mutation passed to fetch. For a plain query string, it's any plain object.
type VariablesOf<Q> = Q extends { readonly __graphqlTypes?: { variables: infer TVariables } }
? TVariables
: Record<string, unknown>;Used by: fetch()
VariantPrice
A variant's price for the customer.
type VariantPrice = {
taxRate: number;
net: number;
gross: number;
currencyCode: string;
taxInclusiveDisplay: boolean; // If true, show gross; otherwise net
};Used by: ProductVariant (price), VariantPriceBreak
VariantPriceBreak
One price break (tier) for a variant: the price per unit from quantity upwards.
type VariantPriceBreak = {
quantity: number;
price: VariantPrice;
unitOfMeasure: string | null;
};Used by: getPricingForVariant(), ProductVariant, ProductVariantPricing
Next steps
Last updated