@liquidcommerce/elements-sdk
Version:
LiquidCommerce Elements SDK
1,183 lines (926 loc) โข 33.2 kB
Markdown
<div align="center">
<h1>
<img src="https://assets.liquidcommerce.co/liquid-commerce-logo/liquid-commerce-light-logo-icon.svg" height="32" width="32" align="top">
Elements SDK
</h1>
</div>
<div align="center">
[](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
[](https://www.typescriptlang.org/)
[](https://www.npmjs.com/)
[](https://pnpm.io/)
[](https://rollupjs.org/)
[](LICENSE)
[](./umd)
[](./package.json)
[](./docs/BROWSER_SUPPORT.md)
**Add product, cart, and checkout experiences to any website with a few lines of code**
</div>
## ๐ Table of Contents
<details>
<summary>Click to expand</summary>
- [Overview](#-overview)
- [Latest Features](#-latest-features)
- [Key Features](#-key-features)
- [Architecture](#-architecture)
- [System Architecture](#system-architecture)
- [Component Architecture](#component-architecture)
- [Event Flow](#event-flow)
- [Features](#-features)
- [Installation](#-installation)
- [CDN Usage](#option-a--use-the-cdn)
- [NPM Installation](#option-b--install-from-npm)
- [Browser Support](#-browser-support)
- [Quick Start](#-quick-start)
- [Auto-initialization](#step-1--auto-initialization-easiest)
- [Product Mapping](#step-2--map-products-to-containers)
- [Programmatic Control](#step-3--programmatic-control-advanced)
- [SDK Methods & API](#-sdk-methods--api)
- [Core Client Methods](#core-client-methods)
- [UI Methods](#ui-methods)
- [Builder Methods](#builder-methods-development-mode)
- [Actions](#-actions)
- [Product Actions](#product-actions)
- [Address Actions](#address-actions)
- [Cart Actions](#cart-actions)
- [Checkout Actions](#checkout-actions)
- [Events](#-events)
- [Event Listening](#event-listening)
- [Available Events](#available-events)
- [Configuration](#-configuration)
- [Module Options](#module-options)
- [Environment Options](#environment-options)
- [Auto-init Attributes](#auto-init-data-attributes)
- [Themes & Customization](#-themes--customization)
- [Theme Configuration](#theme-configuration)
- [Dynamic Updates](#dynamic-theme-updates)
- [Proxy Configuration](#-proxy-configuration)
- [Demo Pages](#-demo-pages)
- [Simple Demo](#simple-demo-demosimplehtml)
- [Advanced Demo](#advanced-demo-demoadvancedhtml)
- [Development Scripts](#-development-scripts)
- [Build Commands](#build-commands)
- [Code Quality](#code-quality-commands)
- [Maintenance](#maintenance-commands)
- [Documentation](#-documentation)
- [Versioning](#-versioning)
- [Support](#-support)
</details>
## ๐ฏ Overview
The LiquidCommerce Elements SDK is a **production-ready JavaScript library** that enables partners to seamlessly integrate product displays, shopping carts, and checkout flows into any website. Built with performance and developer experience in mind.
### ๐ Latest Features
- **Builder Mode**: Dynamic theme customization for development environments
- **Action Feedback Events**: All actions now emit success/failure events for better UX
- **Proxy Support**: Route API requests through your server to avoid ad blockers
- **Enhanced CLI**: Improved development scripts with parallel builds and better error handling
- **TypeScript Support**: Full TypeScript definitions for better IDE experience
### โจ Key Features
<table>
<tr>
<td width="50%">
**๐ Quick Integration**
- Auto-initialization with data attributes
- Zero configuration setup
- CDN or NPM installation
- Works with any framework or vanilla JS
</td>
<td width="50%">
**๐๏ธ Complete E-commerce**
- Product display components
- Shopping cart with real-time updates
- Full checkout flow
- Address management
</td>
</tr>
<tr>
<td width="50%">
**๐จ Customizable UI**
- Comprehensive theme system
- Component-level styling
- Responsive design
- Modern, accessible components
</td>
<td width="50%">
**โก Performance First**
- ~150KB bundle size
- Zero runtime dependencies
- Lazy loading support
- Optimized for Core Web Vitals
</td>
</tr>
</table>
## ๐๏ธ Architecture
### System Architecture
```mermaid
graph TB
subgraph "Your Website"
HTML[HTML Page]
JS[JavaScript]
INIT[Elements SDK]
end
subgraph "Elements SDK Core"
CLIENT[Elements Client]
subgraph "Components"
PROD[Product Component]
CART[Cart Component]
CHECK[Checkout Component]
ADDR[Address Component]
end
subgraph "Services"
ACT[Actions Service]
EVT[Events Service]
API[API Client]
THEME[Theme Provider]
end
subgraph "UI Layer"
BTN[Cart Button]
FLOAT[Floating Cart]
DISP[Live Displays]
end
end
subgraph "LiquidCommerce API"
PAPI[Products API]
CAPI[Cart API]
OAPI[Orders API]
AAPI[Address API]
end
HTML --> INIT
JS --> CLIENT
CLIENT --> PROD
CLIENT --> CART
CLIENT --> CHECK
CLIENT --> ADDR
PROD --> API
CART --> API
CHECK --> API
ADDR --> API
API --> PAPI
API --> CAPI
API --> OAPI
API --> AAPI
ACT --> EVT
CLIENT --> ACT
CLIENT --> THEME
```
### Component Architecture
```mermaid
graph LR
subgraph "Product Component"
PD[Product Display]
PS[Size Selector]
PQ[Quantity Control]
PA[Add to Cart]
end
subgraph "Cart Component"
CI[Cart Items]
CQ[Quantity Update]
CP[Promo Code]
CT[Cart Total]
end
subgraph "Checkout Component"
CS[Shipping Info]
CB[Billing Info]
PM[Payment Method]
OS[Order Summary]
end
PD --> PS
PS --> PQ
PQ --> PA
CI --> CQ
CQ --> CT
CP --> CT
CS --> CB
CB --> PM
PM --> OS
```
### Event Flow
```mermaid
sequenceDiagram
participant User
participant SDK
participant Actions
participant Events
participant API
participant Website
User->>SDK: Add to Cart
SDK->>Actions: cart.addProduct()
Actions->>API: POST /cart/items
API-->>Actions: Response
Actions->>Events: Emit Success/Failure
Events->>Website: lce:actions.cart_product_add_success
Website->>User: Show Feedback
```
## ๐ Features
- **๐ฏ Auto-initialization**: Single script tag with data attributes
- **๐ฆ Zero Dependencies**: Everything bundled, no peer dependencies
- **๐ CDN Ready**: No build step required for basic usage
- **โก Lightweight**: ~150KB minified bundle size
- **๐ง Framework Agnostic**: Works with React, Vue, Angular, or vanilla JS
- **๐ฑ Responsive**: Mobile-first design approach
- **โฟ Accessible**: WCAG 2.1 AA compliant components
- **๐จ Themeable**: Comprehensive customization system
- **๐ Secure**: PCI compliant checkout flow
- **๐ Analytics Ready**: Built-in event system for tracking
- **๐ Multi-environment**: Support for dev, staging, and production
- **๐งช Well Tested**: Comprehensive test coverage
## ๐ฆ Installation
### Choose how to include the SDK
- **Use our CDN** (no build step required)
- **Install from NPM** (for bundlers like Vite, Webpack, etc.)
### Option A โ Use the CDN
Include the script on your page. Use the production or beta URL:
```html
<!-- Production (latest) -->
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
<!-- Beta (latest) -->
<script src="https://assets-elements.liquidcommerce.us/all/beta/elements.js"></script>
```
You can also pin to a specific version:
```html
<script src="https://assets-elements.liquidcommerce.us/all/1.2.3/elements.js"></script>
```
### Option B โ Install from NPM
```bash
npm install @liquidcommerceteam/elements-sdk
# or
pnpm add @liquidcommerceteam/elements-sdk
```
Then import and initialize in your app code:
```js
import { Elements } from '@liquidcommerceteam/elements-sdk';
const client = await Elements('YOUR_API_KEY', {
env: 'production',
});
```
## ๐ Browser Support
โ ๏ธ **Important**: This SDK is designed for browser environments only. It will not work in server-side rendering, Node.js, or other non-browser environments. The SDK includes built-in safety measures to prevent errors when accidentally imported in these environments.
### Supported Browsers
The SDK supports **2018+ browsers** with comprehensive polyfills:
| Browser | Minimum Version | Released |
|---------|----------------|----------|
| Chrome | 66+ | April 2018 |
| Firefox | 60+ | May 2018 |
| Safari | 12+ | September 2018 |
| Edge | 79+ (Chromium) | January 2020 |
| Samsung Internet | 7.2+ | June 2018 |
๐ See [`docs/BROWSER_SUPPORT.md`](docs/BROWSER_SUPPORT.md) for detailed version compatibility and polyfill information.
## ๐ Quick Start
### Step 1 โ Auto-initialization (Easiest)
This single script both loads the SDK and initializes it automatically. Place it:
- At the end of the `<body>` (recommended), or
- In the `<head>` with `defer` so it doesn't block rendering.
```html
<!-- Body footer (recommended) -->
<script
data-liquid-commerce-elements
data-token="YOUR_API_KEY"
data-env="production"
data-cart-id="buttons-container"
data-show-cart-items
src="https://assets-elements.liquidcommerce.us/all/elements.js"
></script>
<!-- OR: Head with defer -->
<script
defer
data-liquid-commerce-elements
data-token="YOUR_API_KEY"
data-env="production"
data-cart-id="buttons-container"
data-show-cart-items
src="https://assets-elements.liquidcommerce.us/all/elements.js"
></script>
```
**Available data attributes:**
- `data-token="YOUR_API_KEY"` - Your API key (required)
- `data-env="production|development"` - Environment (default: production)
- `data-cart-id="container-id"` - ID for cart button container (optional, creates floating button if omitted)
- `data-show-cart-items` - Show items count badge on cart button (optional)
- `data-enable-debugging` - Enable debug logging in development (optional)
Add containers where you want elements to render:
```html
<div id="buttons-container"></div>
<div id="pdp-1"></div>
<div id="pdp-2"></div>
```
### Step 2 โ Map products to containers
Choose one or combine multiple methods:
#### 1) Attribute pairs on the main script
```html
<script
data-liquid-commerce-elements
data-token="YOUR_API_KEY"
data-env="production"
data-container-1="pdp-1"
data-product-1="00619947000020"
data-container-2="pdp-2"
data-product-2="00832889005513"
src="https://assets-elements.liquidcommerce.us/all/elements.js"
></script>
```
#### 2) JSON configuration script
```html
<script data-liquid-commerce-elements-products type="application/json">
[
{ "containerId": "pdp-1", "identifier": "00619947000020" },
{ "containerId": "pdp-2", "identifier": "00832889005513" }
]
</script>
```
#### 3) Annotated elements
```html
<div data-lce-product="00619947000020"></div>
<div data-lce-product="00832889005513"></div>
```
### Step 3 โ Programmatic Control (Advanced)
Initialize the SDK yourself for full control:
```html
<script src="https://assets-elements.liquidcommerce.us/all/elements.js"></script>
<script>
(async () => {
const client = await window.Elements('YOUR_API_KEY', {
env: 'production',
enableDebugging: false, // only for development
customTheme: { /* optional theming overrides */ }
});
// Your implementation here...
})();
</script>
```
## ๐ SDK Methods & API
### Core Client Methods
Once initialized, the client provides these core methods:
#### Product Injection
**`injectProductElement(params: IInjectProductElement[]): Promise<void>`**
Inject product components into containers:
```js
await client.injectProductElement([
{ containerId: 'pdp-1', identifier: '00619947000020' },
{ containerId: 'pdp-2', identifier: '00832889005513' }
]);
```
#### Cart Injection
**`injectCartElement(containerId: string): Promise<void>`**
Inject a cart component:
```js
await client.injectCartElement('cart-container');
```
#### Checkout Injection
**`injectCheckoutElement(containerId: string): Promise<void>`**
Inject a checkout component:
```js
await client.injectCheckoutElement('checkout-container');
```
#### Address Injection
**`injectAddressElement(containerId: string): Promise<void>`**
Inject an address form component:
```js
await client.injectAddressElement('address-container');
```
### UI Methods
#### Cart Buttons
**`ui.cartButton(containerId: string, showItemsCount?: boolean): void`**
Create an "open cart" button in a specific container:
```js
client.ui.cartButton('buttons-container');
// With items count badge
client.ui.cartButton('buttons-container', true);
```
**`ui.floatingCartButton(showItemsCount?: boolean): void`**
Automatically inject a floating cart button:
```js
client.ui.floatingCartButton();
// With items count badge
client.ui.floatingCartButton(true);
```
#### Live Cart Display
**`ui.cartTotal(elementId: string): void`**
Bind an element to display the live cart total (automatically updates when cart changes):
```js
client.ui.cartTotal('cart-total-display');
```
**`ui.cartItemsCount(elementId: string): void`**
Bind an element to display the live cart items count (automatically updates when cart changes):
```js
client.ui.cartItemsCount('cart-items-badge');
```
### Builder Methods (Development Mode)
When `isBuilder: true` is set, additional methods are available for theme customization:
```js
const client = await Elements('YOUR_API_KEY', {
env: 'development',
isBuilder: true
});
// Update component themes
await client.builder.updateComponentGlobalConfigs(globalTheme);
await client.builder.updateProductComponent(productTheme);
client.builder.updateCartComponent(cartTheme);
client.builder.updateCheckoutComponent(checkoutTheme);
client.builder.updateAddressComponent(addressTheme);
// Builder injection methods (same as regular methods)
await client.builder.injectProductElement(params);
await client.builder.injectCartElement(containerId);
await client.builder.injectCheckoutElement(containerId);
await client.builder.injectAddressElement(containerId);
```
## ๐ฌ Actions
Actions provide programmatic control over SDK components. Access them via `client.actions` or `window.elements.actions`:
```js
// Available after client initialization
const actions = client.actions;
// OR globally
const actions = window.elements.actions;
```
### Product Actions
```js
// Get product details
const product = actions.product.getDetails('product-123');
console.log(product.productName, product.price, product.isAvailable);
```
### Address Actions
```js
// Set address using Google Places ID
await actions.address.setAddressByPlacesId('ChIJ0SRjyK5ZwokRp1TwT8dJSv8');
// Set address manually without Google Places (perfect for custom address forms)
await actions.address.setAddressManually(
{
one: '123 Main St',
two: 'Apt 4B', // Optional apartment/suite
city: 'New York',
state: 'NY',
zip: '10001',
country: 'United States' // Optional, will be included in formatted address
},
{
lat: 40.7505045,
long: -73.9934387
}
);
// Listen for success/failure via events
window.addEventListener('lce:actions.address_updated', function(event) {
const address = event.detail.data;
console.log('โ
Address set!', address.formattedAddress);
updateShippingOptions(address.coordinates);
});
window.addEventListener('lce:actions.address_failed', function(event) {
const error = event.detail.data;
console.log('โ Address failed:', error.message);
showAddressForm();
});
// Get current address
const address = actions.address.getDetails();
// Clear saved address
actions.address.clear();
```
**Notes**:
- To find Google Places IDs for the `setAddressByPlacesId` action, use the [Google Places ID Finder](https://developers.google.com/maps/documentation/places/web-service/place-id#find-id)
- The `setAddressManually` action automatically generates a Google Places API-formatted address string from the provided components
- Manual addresses have an empty Places ID (as they don't come from Google Places API)
**Action Feedback**: All actions provide feedback through events. Listen for success/failure events to handle results and provide user feedback.
### Cart Actions
```js
// Control cart visibility
actions.cart.openCart();
actions.cart.closeCart();
actions.cart.toggleCart();
// Add products to cart
await actions.cart.addProduct([{
identifier: 'product-123',
fulfillmentType: 'shipping', // or 'onDemand'
quantity: 2
}]);
// Listen for add product feedback
window.addEventListener('lce:actions.cart_product_add_success', function(event) {
const { itemsAdded, identifiers } = event.detail.data;
console.log(`โ
Added ${itemsAdded} products to cart:`, identifiers);
showSuccessMessage('Products added to cart!');
});
window.addEventListener('lce:actions.cart_product_add_failed', function(event) {
const { identifiers, error } = event.detail.data;
console.log(`โ Failed to add products:`, error);
showErrorMessage('Could not add products. Please try again.');
});
// Apply promo codes
await actions.cart.applyPromoCode('WELCOME10');
// Listen for promo code feedback
window.addEventListener('lce:actions.cart_promo_code_applied', function(event) {
const { applied, discountAmount, newTotal } = event.detail.data;
console.log(`โ
Promo applied! Discount: $${discountAmount}, New total: $${newTotal}`);
showSavingsMessage(discountAmount);
});
window.addEventListener('lce:actions.cart_promo_code_failed', function(event) {
const { attempted, error } = event.detail.data;
console.log(`โ Promo failed:`, error);
showErrorMessage('Promo code could not be applied');
});
// Remove promo codes
await actions.cart.removePromoCode();
// Get cart details
const cart = actions.cart.getDetails();
console.log(cart.total, cart.items.length);
// Reset cart
await actions.cart.resetCart();
```
### Checkout Actions
```js
// Control checkout visibility
actions.checkout.openCheckout();
actions.checkout.closeCheckout();
actions.checkout.toggleCheckout();
// Pre-fill customer information
actions.checkout.updateCustomerInfo({
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
phone: '+1234567890'
});
// Pre-fill billing information
actions.checkout.updateBillingInfo({
firstName: 'John',
lastName: 'Doe',
street1: '123 Main St',
city: 'Anytown',
state: 'CA',
zipCode: '12345'
});
// Manage gift options
await actions.checkout.toggleIsGift(true);
actions.checkout.updateGiftInfo({
giftMessage: 'Happy Birthday!',
giftFrom: 'Your Friend'
});
// Apply discounts and gift cards
await actions.checkout.applyPromoCode('SAVE20');
await actions.checkout.applyGiftCard('GIFT123');
// Listen for checkout promo code feedback
window.addEventListener('lce:actions.checkout_promo_code_applied', function(event) {
const { applied, discountAmount, newTotal } = event.detail.data;
console.log(`โ
Checkout promo applied! Saved: $${discountAmount}`);
updateCheckoutTotal(newTotal);
});
window.addEventListener('lce:actions.checkout_promo_code_failed', function(event) {
const { attempted, error } = event.detail.data;
console.log(`โ Checkout promo failed:`, error);
showCheckoutError('Promo code could not be applied');
});
// Listen for gift card feedback
window.addEventListener('lce:actions.checkout_gift_card_applied', function(event) {
const { applied, newTotal } = event.detail.data;
console.log('โ
Gift card applied successfully!');
updateCheckoutTotal(newTotal);
showSuccessMessage('Gift card applied to your order');
});
window.addEventListener('lce:actions.checkout_gift_card_failed', function(event) {
const { attempted, error } = event.detail.data;
console.log(`โ Gift card failed:`, error);
showCheckoutError('Gift card could not be applied');
});
// Get checkout details (safe, non-sensitive data only)
const checkout = actions.checkout.getDetails();
console.log('Total:', checkout.amounts.total);
console.log('Items:', checkout.itemCount);
console.log('Is gift:', checkout.isGift);
console.log('Has age verification:', checkout.hasAgeVerify);
console.log('Has promo code:', checkout.hasPromoCode);
console.log('Has gift cards:', checkout.hasGiftCards);
// Configure checkout options
await actions.checkout.toggleBillingSameAsShipping(true);
actions.checkout.toggleMarketingPreferences('canEmail', true);
```
See [`docs/ACTIONS.md`](docs/ACTIONS.md) for complete action reference with business use cases.
## ๐ก Events
The SDK emits real-time events for all user interactions. Listen to these events to trigger custom behavior:
```js
// Listen for specific events
window.addEventListener('lce:actions.product_add_to_cart', function(event) {
const product = event.detail.data;
console.log('Added to cart:', product.productName);
// Your custom logic here
analytics.track('Product Added', {
product: product.productName,
price: product.price
});
});
// Or use the helper methods (available after initialization)
window.elements.onAllForms((data, metadata) => {
console.log('Form Event', { data, metadata });
});
window.elements.onAllActions((data, metadata) => {
console.log('Action Event', { data, metadata });
});
```
### Available Events
#### Product Events
- `lce:actions.product_loaded` - Product component loaded
- `lce:actions.product_add_to_cart` - Item added to cart
- `lce:actions.product_quantity_increase` - Quantity increased
- `lce:actions.product_quantity_decrease` - Quantity decreased
- `lce:actions.product_size_changed` - Product size/variant changed
- `lce:actions.product_fulfillment_type_changed` - Delivery method changed
#### Cart Events
- `lce:actions.cart_opened` - Cart displayed
- `lce:actions.cart_closed` - Cart hidden
- `lce:actions.cart_updated` - Cart contents changed
- `lce:actions.cart_item_added` - Item added
- `lce:actions.cart_item_removed` - Item removed
- `lce:actions.cart_reset` - Cart cleared
#### Checkout Events
- `lce:actions.checkout_opened` - Checkout started
- `lce:actions.checkout_closed` - Checkout abandoned
- `lce:actions.checkout_submit_started` - Order submission began
- `lce:actions.checkout_submit_completed` - Order completed successfully
- `lce:actions.checkout_submit_failed` - Order failed
- `lce:actions.checkout_customer_information_updated` - Customer info entered
- `lce:actions.checkout_billing_information_updated` - Billing info entered
#### Address Events
- `lce:actions.address_updated` - Address information changed
- `lce:actions.address_cleared` - Address removed
See [`docs/EVENTS.md`](docs/EVENTS.md) for complete event reference with implementation examples.
## โ๏ธ Configuration
Configure the SDK when initializing:
```js
const client = await Elements('YOUR_API_KEY', {
env: 'production', // 'local' | 'development' | 'staging' | 'production'
enableDebugging: false, // Enable console logging (development only)
isBuilder: false, // Enable builder methods (development only)
customTheme: { /* theme overrides */ },
proxy: { /* proxy configuration */ }
});
```
### Environment Options
- **`production`**: Live environment for customer-facing sites
- **`staging`**: Pre-production testing environment
- **`development`**: Development environment with additional debugging
- **`local`**: Local development environment
### Auto-init Data Attributes
When using auto-initialization, configure via data attributes:
- `data-liquid-commerce-elements`: Required flag to enable auto-init
- `data-token`: Your API key (required)
- `data-env`: Environment (defaults to production)
- `data-cart-id`: Container ID for cart button
- `data-enable-debugging`: Enable debugging mode
- `data-container-X` / `data-product-X`: Product mapping pairs
## ๐จ Themes & Customization
Customize the appearance of SDK components using the theme system:
```js
const client = await Elements('YOUR_API_KEY', {
env: 'production',
customTheme: {
global: {
colors: {
primary: '#007bff',
secondary: '#6c757d'
},
typography: {
fontFamily: 'Roboto, sans-serif',
fontSize: '16px'
}
},
product: {
layout: {
imagePosition: 'left',
showDescription: true
},
colors: {
price: '#28a745',
sale: '#dc3545'
}
},
cart: {
layout: {
showRetailerLogos: true,
compactMode: false
}
},
checkout: {
layout: {
singlePage: true,
showOrderSummary: true
}
}
}
});
```
In builder mode, themes can be updated dynamically:
```js
// Update themes in real-time (builder mode only)
await client.builder.updateComponentGlobalConfigs({
colors: { primary: '#ff6b6b' }
});
await client.builder.updateProductComponent({
layout: { imagePosition: 'right' }
});
```
## ๐ Proxy Configuration
Route API requests through your server to avoid ad blockers:
```js
const client = await Elements('YOUR_API_KEY', {
env: 'production',
proxy: {
baseUrl: 'https://yourdomain.com/api/liquidcommerce',
headers: {
'X-Custom-Header': 'value'
}
}
});
```
The SDK automatically handles routing and required headers. See [`docs/PROXY.md`](docs/PROXY.md) for complete proxy setup guide with Next.js examples.
## ๐ Documentation
For detailed guides and advanced usage:
- [`docs/ACTIONS.md`](docs/ACTIONS.md) - Complete actions reference with business use cases
- [`docs/EVENTS.md`](docs/EVENTS.md) - Events guide with implementation examples
- [`docs/BROWSER_SUPPORT.md`](docs/BROWSER_SUPPORT.md) - Detailed browser compatibility
- [`docs/PROXY.md`](docs/PROXY.md) - Proxy configuration for ad blocker avoidance
## ๐ท๏ธ Versioning
This project uses Semantic Versioning. The SDK is available in two environments:
### Beta Environment
- Branch: `beta`
- Base URL: `https://assets-elements.liquidcommerce.us/all/beta/`
- Purpose: Testing and pre-release features
### Production Environment
- Branch: `main`
- Base URL: `https://assets-elements.liquidcommerce.us/all/`
- Purpose: Stable releases for production use
### CDN Path Structure
```
elements-sdk/
โโโ all/
โโโ beta/
โ โโโ 1.2.3/elements.js
โ โโโ 1.2.4/elements.js
โ โโโ elements.js (beta latest)
โโโ 1.2.2/elements.js (production)
โโโ 1.2.3/elements.js (production)
โโโ elements.js (production latest)
```
## ๐ญ Demo Pages
The SDK includes ready-to-use demo pages in the `demo/` folder that showcase different implementation approaches:
### Simple Demo (`demo/simple.html`)
Demonstrates **auto-initialization** using data attributes - the easiest way to get started:
```html
<!-- Auto-init with data attributes -->
<script
data-liquid-commerce-elements
data-token="YOUR_API_KEY"
data-env="development"
data-enable-debugging
src="../umd/elements.js"
></script>
```
**Features shown:**
- Auto-initialization with data attributes
- Multiple product mapping methods (data attributes, JSON script, annotated elements)
- Event listening for actions and forms
- Basic container setup for products, cart, and checkout
**Best for:** Quick prototyping, simple integrations, getting familiar with the SDK
### Advanced Demo (`demo/advanced.html`)
Demonstrates **programmatic initialization** for full control:
```javascript
const client = await window.Elements(API_KEY, {
env: "development",
enableDebugging: true,
customTheme: { /* theme config */ }
});
// Programmatic component injection
client.buttons.openCart("buttons-container");
await client.injectProductElement([
{ containerId: "pdp-container", identifier: '00619947000020' }
]);
await client.injectCheckoutElement("checkout-container");
```
**Features shown:**
- Manual client initialization with full configuration
- Programmatic component injection
- Builder methods for theme updates (commented examples)
- Advanced event handling
- Dynamic theme updates
**Best for:** Complex integrations, custom workflows, theme customization, production implementations
### Running the Demos
1. **Clone the repository**
2. **Open demo files** in your browser
3. **Update API keys** with your own credentials
4. **Modify environment** settings as needed (`development`, `staging`, `production`)
The demos use local UMD builds (`../umd/elements.js`) but can be easily switched to CDN URLs for testing.
## ๐ ๏ธ Development Scripts
For SDK development and maintenance, the following npm/pnpm scripts are available:
### Build Commands
**`build`** - Production build
```bash
pnpm run build
```
- Creates optimized ESM and UMD bundles for production
- Generates TypeScript declarations
- Enables minification and compression
- Removes console logs and debugging code
- **Output:** `dist/index.esm.js` (ESM) + `umd/elements.js` (UMD)
**`build:dev`** - Development build
```bash
pnpm run build:dev
```
- Creates unminified bundles with source maps
- Preserves console logs and debugging code
- Faster build times for development
- **Output:** Same as build but with debugging enabled
**`dev`** - Development with watch mode
```bash
pnpm run dev
```
- Same as `build:dev` but watches for file changes
- Automatically rebuilds on source code changes
- **Best for:** Active development
### Code Quality Commands
**`lint`** - Lint and auto-fix code
```bash
pnpm run lint
```
- Uses Biome to lint TypeScript/JavaScript files
- Automatically fixes fixable issues
- Enforces code style and catches common errors
**`format`** - Format code
```bash
pnpm run format
```
- Uses Biome to format all source files
- Ensures consistent code formatting
- Applies formatting rules defined in `biome.json`
**`check`** - Combined linting and formatting
```bash
pnpm run check
```
- Runs both linting and formatting in one command
- Auto-fixes issues and formats code
- **Recommended before commits**
**`fl`** - Format, lint, and build (Fast Loop)
```bash
pnpm run fl
```
- Combines `check` + `build:dev`
- Complete code quality check + development build
- **Perfect for:** Pre-commit workflow
### Maintenance Commands
**`clean`** - Clean build outputs
```bash
pnpm run clean
```
- Removes `dist/` and `umd/` directories
- **Use when:** Build artifacts are corrupted
**`clean:hard`** - Complete reset
```bash
pnpm run clean:hard
```
- Removes build outputs AND `node_modules/`
- Reinstalls all dependencies with `pnpm install`
- Runs a fresh production build
- **Use when:** Dependency issues or major updates
**`changelog`** - Generate changelog
```bash
pnpm run changelog
```
- Generates `CHANGELOG.md` from conventional commits
- Uses Angular commit convention
- **Use when:** Preparing releases
### Build Configuration
The build system uses **Rollup** with different configurations:
#### ESM Build (`dist/index.esm.js`)
- **Target:** Modern bundlers (Vite, Webpack, etc.)
- **Format:** ES Modules
- **Optimizations:** Tree shaking, modern syntax
- **Use case:** NPM package imports
#### UMD Build (`umd/elements.js`)
- **Target:** Direct browser usage
- **Format:** Universal Module Definition
- **Global:** `window.LiquidCommerceElements`
- **Optimizations:** Maximum browser compatibility
- **Use case:** CDN distribution, `<script>` tags
#### Development vs Production
- **Development:** Source maps, preserved logging, faster builds
- **Production:** Minified, compressed, optimized for size
### Recommended Workflows
**Development Workflow:**
```bash
# Start development
pnpm run dev
# Before committing
pnpm run fl
```
**Release Workflow:**
```bash
# Clean and build for release
pnpm run clean:hard
# Generate changelog
pnpm run changelog
# Build is run automatically on publish
```
**Troubleshooting:**
```bash
# If builds are failing
pnpm run clean:hard
# For code quality issues
pnpm run check
```
## ๐ฌ Support
If you need help with your API key, environment selection, or implementation, contact your LiquidCommerce representative.
---
<div align="center">
**Built with โค๏ธ by the LiquidCommerce Team**
[Actions Reference](docs/ACTIONS.md) โข [Events Guide](docs/EVENTS.md) โข [Browser Support](docs/BROWSER_SUPPORT.md) โข [Proxy Setup](docs/PROXY.md)
</div>