---
title: "Core Library"
description: "Reference for bolder-storefront's core modules — the loader, request client, and each engine wrapped by createStorefront()."
---


Auto-generated from the JSDoc blocks in `assets/js/storefront/src/core/*.js` — the source of `bolder-storefront`'s Core API. For narrative guides (quick start, cart, checkout, ...) see the rest of this section.

## Auth

Customer authentication — log in, register, OTP verification, and password reset. Access via: Bolder.call('Auth', 'methodName', args, callback)

| Method | Description |
|--------|-------------|
| `login(email, password, cb)` | Log in a customer with email and password. |
| `createAccount(body, cb)` | Create a new customer account. body: \{ email, password, name, ... \}. |
| `validateOTPCode(email, otp, otpMode, activationToken, password, customPhone, cb)` | Validate a one-time password code. |
| `resendOTPCode(email, otpMode, customPhone, cb)` | Resend an OTP code to the customer. |
| `forgotPassword(email, cb)` | Send a password reset email. |
| `checkExists(email, cb)` | Check whether a customer account exists for the given email. |
| `oauthLogin(provider)` | Initiate an OAuth login flow. provider: 'google' or 'github'. |

## Base

Base utilities — path/environment helpers, cookies, storage, and general-purpose helpers used across core modules. Access via: Bolder.call('Base', 'methodName', args, callback)

| Method | Description |
|--------|-------------|
| `isCustomizing()` | Returns true if the storefront is being previewed in the theme editor or in local development. |
| `inEditor()` | Returns true if the current page is loaded inside the theme customizer. |
| `inDevelopment()` | Returns true if the current page is loaded via the local preview/dev path. |
| `getPath(path)` | Rewrites a path to the local preview/dev path when in development mode. |
| `setCookie(name, value, days)` | Sets a cookie. |
| `getCookie(name)` | Reads a cookie value. |
| `delCookie(name)` | Removes a cookie. |
| `store` | localStorage when available (and not cross-origin framed), otherwise falls back to cookies. |
| `formatPrice(n, decPlaces, thouSeparator, decSeparator)` | Formats a number as a currency string. |
| `formatCurrency(value)` | Adds thousands separators to a numeric string. |
| `parseQuery(str, nested)` | Parses a querystring into a key/value object. |
| `generateRandomId()` | Returns a random id string, used for session/pixel ids. |

## Browser

Browser/OS/device sniffing, used to enrich landing/session data (see user.js). Access via: Bolder.call('Browser', 'methodName', args, callback)

| Method | Description |
|--------|-------------|
| `detect(nav)` | Returns `{ device_type, browser_name, browser_version, os_name, distro? }` for the given (or current) navigator. |

## Cart

Cart management — add, remove and update line items; listen to cart events. Access via: Bolder.cart (hosted theme) or storefront.cart (headless).

| Method | Description |
|--------|-------------|
| `quickAdd(productIdOrSlug, fn?)` | Add a product by numeric ID or by URL slug, using its default variant. Slugs are resolved server-side. |
| `addItem(productId, variantId, qty, formData?, fn?)` | Add or increase quantity of a line item. If the same variant already exists, its quantity is increased. |
| `addVariant(variantId, qty, fn?)` | Add by variant ID without specifying a product ID. |
| `addBundle(productId, formData, qty, fn?)` | Add a bundle product with its selected variants. |
| `addMany(items, fn?)` | Add multiple items at once. Items not found in the response are reported as errors. |
| `addGiftCard(productId, qty, formData, fn?)` | Add a gift-card product. |
| `updateUnits(itemId, units, fn?)` | Update the quantity of an existing line item. No-op if quantity is unchanged. |
| `increaseItem(item, units?, fn?)` | +/- button decision logic: bumps quantity, or no-ops if overbought (returns false). |
| `decreaseItem(item, units?, fn?)` | +/- button decision logic: decrements quantity, or removes the item once it would hit zero. |
| `changeItemQuantity(item, newUnits, fn?)` | Sets an arbitrary quantity, removing the item if newUnits &lt;= 0. |
| `remove(itemId, fn?)` | Remove a line item by its cart item ID. |
| `load(fn?)` | Load cart data from the server. Calls fn(cart) on completion. |
| `isLoaded()` | Returns true if the cart has been loaded at least once. |
| `isEmpty()` | Returns true if the cart has no items. |
| `findByItemId(id)` | Find a line item by its cart item ID. |
| `findByVariantId(id)` | Find a line item by variant ID. |
| `findByProductId(id)` | Find a line item by product ID. |
| `on(event, handler)` | Register an event listener. |
| `off(event, handler?)` | Remove an event listener. |
| `once(event, handler)` | Register a one-time event listener. |

| Event | Description |
|-------|-------------|
| `loading` | Cart load started. |
| `loaded` | Cart loaded successfully. |
| `adding` | Add request started (args: item, srcElement). |
| `added` | Item successfully added (args: item, srcElement). |
| `adding_failed` | Item not found in response after add. |
| `updating` | Update request started (args: \{ id, quantity \}, srcElement). |
| `updated` | Cart data refreshed; fires after every mutation. |
| `updated_item` | Specific item quantity confirmed by server (args: item, srcElement). |
| `update_failed` | Server quantity did not match requested value. |
| `removing` | Remove request started (args: item, srcElement). |
| `removed` | Item successfully removed (args: item, srcElement). |
| `cleared` | All items removed. |
| `error` | A cart operation failed (args: message). |

## CartDecorator

Computes the per-item/cart display flags the cart-table templates (v1 and v3) check directly — can_change_quantity, has_description, etc. Neither the raw cart JSON nor createCart()'s own _decorateProducts() (cart.js) compute these; they used to live only inside the hosted-theme legacy DynamicCartTable Loader module's renderCart(), so headless-rendered cart tables (ShoppingBeacon, the SDK's CartTable) silently rendered without quantity controls, descriptions, or the promotions panel. One implementation, two callers — dynamic_cart_table.js and cart-table-v3's beforeUpdate() — mirroring how SearchSocket is shared between the headless search API and the legacy SearchIndex adapter.

## CartRules

Validates a cart against shop-configured order requirements (min/max order total, min/max order weight, units per product/product-type/variant, quantity multiples, product group presence/absence, customer-group/branch restrictions), returning one ready-to-show message (may contain inline HTML like &lt;strong&gt;, but never block-level wrapping like &lt;li&gt;/&lt;ul&gt; — that's the caller's rendering layout to decide) per unmet requirement. Shared by the hosted theme's legacy CartRules Loader module (modules/cart/cart_rules.js, which injects the messages directly as DOM HTML) and cart-table-v3's headless beforeUpdate() (which hands them to the qiq template to wrap in &lt;li&gt; and loop over) — same shape as cart-decorator.js. `requirements` defaults to `cart.rules`, which the server already includes on the cart JSON response in both hosted and headless mode (see core/cart.js's update()), so no extra config wiring is needed to use this headlessly.

## Delivery

Shipping and delivery — fetch countries, regions, costs, and branch information. Access via: Bolder.call('Delivery', 'methodName', args, callback)

| Method | Description |
|--------|-------------|
| `getShippingCountries(cb)` | Fetch all countries the store ships to. |
| `getShippingRegions(params, cb)` | Fetch regions for a country. params: \{ country_code \}. |
| `getShippingOptions(address, weight, withWindows?, branchId?, cb)` | Calculate shipping costs for an address and package weight. |
| `getShippingBranches(params, cb)` | Fetch all configured shipping branches. |
| `getPickupBranches(cb)` | Fetch branches available for customer pickup. |
| `getFulfillmentBranches(cb)` | Fetch branches available for order fulfillment. |
| `getFulfillmentOptions(address, weight, withWindows?, cb)` | Calculate fulfillment options for an address. |
| `getShippingPolygons(params, cb)` | Fetch shipping zone polygons for map display. |

## Dom

DOM utilities — element selection, creation, and traversal including Shadow DOM support. Access via: Bolder.DOM (hosted theme) or via Util (util.$, util.find, etc).

| Method | Description |
|--------|-------------|
| `ready(fn)` | Run fn when the DOM is ready (or immediately if already loaded). |
| `find(selector, context?)` | Return an array of elements matching the CSS selector. |
| `get(selector, context?, ensure?)` | Return the first matching element (or throw if ensure is true). |
| `deepFind(selector, root?)` | Like find() but traverses into Shadow DOM subtrees. |
| `deepGet(selector, context?, ensure?)` | Like get() but traverses into Shadow DOM subtrees. |
| `each(selector, context?, fn)` | Iterate over all matching elements calling fn(el). |
| `el(tag, html?, opts?)` | Create and return a new DOM element with optional inner HTML and properties. |
| `is(el, selector)` | Return true if el matches the given CSS selector. |

## Events

DOM event helpers and a tiny pub/sub `Emitter` used across cart, delivery, and other modules. Access via: Bolder.call('Events', 'methodName', args, callback), or `new Emitter()` directly.

| Method | Description |
|--------|-------------|
| `on(el, type, selector, callback)` | Listen for an event, optionally delegated to a child selector. |
| `off(el, type, selector, callback)` | Remove an event listener registered with `on`. |
| `once(el, type, selector, callback)` | Listen for an event once, then automatically remove the listener. |
| `trigger(el, eventName, data, opts)` | Dispatch a DOM event (native `click` or a `CustomEvent`) on an element. |
| `Emitter(obj)` | Mixes `on`/`once`/`off`/`trigger` pub/sub methods into an object, or returns a new emitter. |

## Forms

Contact forms — fetch field definitions and submit form data for headless storefronts. Useful for building a contact/feedback form outside of a Bolder theme (e.g. a statically-generated site) while still delivering submissions to the shop's contacts. Access via: storefront.forms (headless).

| Method | Description |
|--------|-------------|
| `get(slug, fn)` | Fetch a form's field definitions. Calls fn(err, form) with form: \{ id, slug, title, message, sentMessageText, contactFields, customFields \}. Each field: \{ key, name, field_type, required, value, options? \}. |
| `submit(form, data, fn)` | Submit form data. form: the object returned by get(). data: \{ fieldKey: value, ... \}, keyed by each field's `key`. Calls fn(err, result) with result: \{ success: true \} on success, or \{ success: false, errors \} on validation failure. |

## Loader

AMD-style module loader — resolves modules by name (not path). Backs `Bolder.Loader` and `Bolder.call`/`Bolder.require`. Access via: Bolder.Loader.methodName(args)

| Method | Description |
|--------|-------------|
| `define(name, deps, fn)` | Registers a module under a name, resolving its dependencies first. |
| `require(name1, name2, ..., cb)` | Requires one or more registered modules and calls back with their instances. |
| `requireMany(queue, finished)` | Requires several groups of modules in sequence. |
| `load(name, opts, cb)` | Loads a module (calling its `load` method) with the given options. |
| `loadMany(list, finished)` | Loads several modules in sequence. |
| `unload(name, obj, cb)` | Unloads a previously loaded module instance, or all instances. |
| `isLoaded(name)` | Returns true if a module has an active loaded instance. |
| `call(moduleName, method, ...args)` | Requires a module and calls a method on it, e.g. `Bolder.call('Cart', 'open')`. |
| `addAlias(existingModule, newName)` | Registers an existing module under an additional name. |

## Plans

Membership plans, as plain JSON — for headless storefronts. Access via: storefront.plans (headless). Unauthenticated, public read.

| Method | Description |
|--------|-------------|
| `get(fn)` | Fetch membership plans. Calls fn(err, plans) with plans: an array of \{ id, name, description, url, images, attributes, subscription_fees \}. Each subscription_fees entry: \{ id, setup_fee, renewal_fee, payment_interval, interval_label, variant_id \} (amounts are numeric, smallest-currency-unit). Errors (via err) if the shop has disabled the plans page. |

## Points

Points-club policy, as plain JSON — for headless storefronts. Access via: storefront.points (headless). Unauthenticated, public read.

| Method | Description |
|--------|-------------|
| `get(fn)` | Fetch the shop's points-club policy config (naming, earn/expiration rules, an example earn calculation, contact channel) — not a customer's balance, see buyer_points under Customer Console for that. Calls fn(err, policy) with policy: \{\} if the shop has the points-club addon but no settings configured; errors (via err) if the addon isn't enabled at all. |

## Products

Product catalog — list/filter products for headless storefronts. Access via: storefront.products (headless).

| Method | Description |
|--------|-------------|
| `get(params?, fn)` | List products, optionally filtered. params: \{ q, collections, product_types, vendors, tags, price_gte, price_lte, page, facets \}. Calls fn(err, data) with data: \{ products, page, per_page, total_items, total_pages, facets \}. |
| `related(productSlug, fn)` | Fetch products related to the given product (by tag or collection), for cross-sell widgets. Items already in the cart are excluded automatically when a cart instance was passed to createProducts. Calls fn(err, products). |
| `getForCart(productSlug, fn)` | Fetch a single product in cart-ready shape: variant_list/variant_options (the color/size matrix, for multi-axis variant selection), bundle_config, modifiers, subscription_fees. Calls fn(err, product). |

## Promos

Promotions, as plain JSON — for headless storefronts. Access via: storefront.promos (headless). Unauthenticated, public read.

| Method | Description |
|--------|-------------|
| `get(fn)` | Fetch the shop's visible/eligible promotions. Calls fn(err, promos) with promos: an array shaped like \{ id, discount, discount_type, name, automatic, full_discount, ... \}. Errors (via err) if the shop has disabled the promos page. |

## Request

Simple XHR wrapper used for all AJAX calls (hosted theme) plus a factory for scoped, cross-origin-aware request functions used by the headless `bolder-storefront` client. Access via: Bolder.call('Request', 'methodName', args, callback), or the default export directly.

| Method | Description |
|--------|-------------|
| `ajax(method, url, data, onsuccess, onerror, headers)` | Make an XHR request. JSON-encodes data for `.json`/`.js` URLs, form-serializes otherwise. |
| `createRequest(baseUrl, opts)` | Returns a request function scoped to a base URL; pass `opts.withCredentials` for cross-origin requests needing session cookies, `opts.getHeaders()` for per-request extra headers. |

## Search

Live product search — WebSocket-backed typeahead search. Access via: storefront.search (headless) or Bolder.call('SearchIndex', ...) (hosted theme, legacy API).

| Method | Description |
|--------|-------------|
| `connect(fn?)` | Opens (or reuses) the search connection. Calls fn(err, socket). Rarely needed directly - search() and bindTo() both connect automatically; use it to pre-warm the connection (e.g. on input focus) so the first keystroke doesn't pay connection latency. |
| `search(query, opts?, fn)` | Runs a single query. Auto-connects if needed. Calls fn(err, results). |
| `bindTo(input, opts?)` | Wires an &lt;input&gt; element to live search: connects on focus (pre-warms latency), searches on debounced input, lets the connection's own inactivity timeout handle disconnecting. Returns an Emitter with a destroy() method to unbind. |

| Event | Description |
|-------|-------------|
| `results` | A query returned results (args: results, query). |
| `error` | The query or connection failed (args: error). |
| `cleared` | The input emptied below minChars (no args). |

## SearchHttpClient

Plain-HTTP fallback for SearchSocket, used when a WebSocket connection to product-search-worker can't be established (corporate proxy blocking the upgrade handshake, browser with no WebSocket support, etc). Hits the same server-side index/query-understanding via GET /search on the worker - NOT a "fetch search.json and match client-side" fallback (some shops' feeds are 1MB+), just a different transport for the same computation. Deliberately much simpler than SearchSocket: there's no persistent connection, so none of the reconnect/heartbeat/resend/inactivity-timer machinery applies - each search() is a single request/response.

## SearchSocket

Low-level WebSocket client for the product search service. Shared by the headless `search.js` API and the hosted-theme legacy `SearchIndex` adapter (registered in register-amd.js) — one implementation, two callers. No Bolder/DOM dependency beyond WebSocket/localStorage/crypto.

## Templates

Client-side template compilation and rendering, backed by the `qiq2` engine. Access via: Bolder.call('Templates', 'methodName', args, callback)

| Method | Description |
|--------|-------------|
| `compile(templateName, body)` | Compile and cache a template string under a name. |
| `render(templateNameOrBody, data)` | Render a cached template by name, or compile-and-render a raw template string. |
| `renderRaw(body, data)` | Compile and render a template string without caching it. |
| `renderCached(templateName, data)` | Render an already-compiled template by name. Throws if not found. |
| `loadAndCompile(elementId, templateId)` | Compile a template from a `<script>` element's contents. |
| `loadAndRender(elementId, content)` | Load-and-compile (if needed) then render a template from a `<script>` element. |
| `isCompiled(templateName)` | Returns true if a template has already been compiled. |
| `setEngine(obj, opts)` | Swap the underlying template engine and its options. |

## User

User session — read session data, cookies, and navigation history. Access via: Bolder.call('User', 'methodName', args, callback)

| Method | Description |
|--------|-------------|
| `getJSONCookie(cookieName)` | Parse and return a JSON-encoded cookie value. |
| `getCurrentData(cb)` | Fetch the current customer's session data from the server. |
| `getUrlHistory()` | Returns the last 10 visited page paths as an array. |
| `getMembership(cb)` | Returns `{ id, plan_id, plan_name }` if the customer has an active membership, or null. |

## Util

General-purpose utilities — event helpers, DOM querying, AJAX, scroll/intersection observers, product fetching, and more. Access via: Bolder.util (hosted theme) or window.Bolder.util.

| Method | Description |
|--------|-------------|
| `debounce(fn, wait, immediate?)` | Return a debounced version of fn that delays execution until wait ms after the last call. |
| `$(selector, context?)` | Select DOM element(s); returns a DOMNode wrapper with helper methods. |
| `on(el, event, fn)` | Attach an event listener to one or more elements. |
| `off(el, event, fn)` | Remove an event listener from one or more elements. |
| `once(el, event, fn)` | Attach an event listener that fires only once. |
| `trigger(el, event, data?)` | Dispatch a custom DOM event, optionally with extra data. |
| `ajax(url, opts?)` | Make an HTTP request. Returns a promise-like object. opts: method, data, headers, type. |
| `serialize(form)` | Serialize a form element into a query string. |
| `sendForm(form, opts?)` | Submit a form via AJAX, returning the JSON response. |
| `streamGet(url, opts?)` | GET a URL and stream the response line by line via opts.onData(line). |
| `onScroll(el, fn)` | Call fn(entry) each time el enters or leaves the viewport during scroll. |
| `onIntersect(el, fn, opts?)` | Call fn(isIntersecting) when el intersects the viewport (IntersectionObserver wrapper). |
| `isTouchDevice()` | Return true if the current device supports touch input. |
| `getProduct(shopId, productId, opts?)` | Fetch a single product from the Bolder API. Returns a promise. |
| `getProductAt(shopId, urlPath, opts?)` | Fetch the product at a given URL path. |
| `getProductForCart(shopId, productId, opts?)` | Fetch a product formatted for cart use. |
| `getMenu(shopId, menuHandle, opts?)` | Fetch a navigation menu by handle. |
| `isDark(color)` | Return true if the given hex/rgb color is perceptually dark. |
| `isLight(color)` | Return true if the given hex/rgb color is perceptually light. |
| `loadImage(src)` | Load an image and return a promise that resolves when loaded. |
| `loadImages(els)` | Load all img elements in the given list. |
| `sha256(message)` | Return a SHA-256 hex digest of message (returns a Promise). |
| `tabList(el, opts?)` | Enhance a list of tabs with keyboard navigation and active-state management. |
| `selectize(el, opts?)` | Enhance a &lt;select&gt; element with a searchable custom dropdown. |

