
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
@liquidcommerce/elements-sdk
Advanced tools
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.
๐ Quick Integration
|
๐๏ธ Complete E-commerce
|
๐จ Customizable UI
|
โก Performance First
|
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
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
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
Include the script on your page. Use the production or beta URL:
<!-- 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:
<script src="https://assets-elements.liquidcommerce.us/all/1.2.3/elements.js"></script>
npm install @liquidcommerceteam/elements-sdk
# or
pnpm add @liquidcommerceteam/elements-sdk
Then import and initialize in your app code:
import { Elements } from '@liquidcommerceteam/elements-sdk';
const client = await Elements('YOUR_API_KEY', {
env: 'production',
});
โ ๏ธ 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.
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
for detailed version compatibility and polyfill information.
This single script both loads the SDK and initializes it automatically. Place it:
<body>
(recommended), or<head>
with defer
so it doesn't block rendering.<!-- 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:
<div id="buttons-container"></div>
<div id="pdp-1"></div>
<div id="pdp-2"></div>
Choose one or combine multiple methods:
<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>
<script data-liquid-commerce-elements-products type="application/json">
[
{ "containerId": "pdp-1", "identifier": "00619947000020" },
{ "containerId": "pdp-2", "identifier": "00832889005513" }
]
</script>
<div data-lce-product="00619947000020"></div>
<div data-lce-product="00832889005513"></div>
Initialize the SDK yourself for full control:
<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>
Once initialized, the client provides these core methods:
injectProductElement(params: IInjectProductElement[]): Promise<void>
Inject product components into containers:
await client.injectProductElement([
{ containerId: 'pdp-1', identifier: '00619947000020' },
{ containerId: 'pdp-2', identifier: '00832889005513' }
]);
injectCartElement(containerId: string): Promise<void>
Inject a cart component:
await client.injectCartElement('cart-container');
injectCheckoutElement(containerId: string): Promise<void>
Inject a checkout component:
await client.injectCheckoutElement('checkout-container');
injectAddressElement(containerId: string): Promise<void>
Inject an address form component:
await client.injectAddressElement('address-container');
ui.cartButton(containerId: string, showItemsCount?: boolean): void
Create an "open cart" button in a specific container:
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:
client.ui.floatingCartButton();
// With items count badge
client.ui.floatingCartButton(true);
ui.cartTotal(elementId: string): void
Bind an element to display the live cart total (automatically updates when cart changes):
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):
client.ui.cartItemsCount('cart-items-badge');
When isBuilder: true
is set, additional methods are available for theme customization:
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 provide programmatic control over SDK components. Access them via client.actions
or window.elements.actions
:
// Available after client initialization
const actions = client.actions;
// OR globally
const actions = window.elements.actions;
// Get product details
const product = actions.product.getDetails('product-123');
console.log(product.productName, product.price, product.isAvailable);
// 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:
setAddressByPlacesId
action, use the Google Places ID FindersetAddressManually
action automatically generates a Google Places API-formatted address string from the provided componentsAction Feedback: All actions provide feedback through events. Listen for success/failure events to handle results and provide user feedback.
// 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();
// 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
for complete action reference with business use cases.
The SDK emits real-time events for all user interactions. Listen to these events to trigger custom behavior:
// 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 });
});
lce:actions.product_loaded
- Product component loadedlce:actions.product_add_to_cart
- Item added to cartlce:actions.product_quantity_increase
- Quantity increasedlce:actions.product_quantity_decrease
- Quantity decreasedlce:actions.product_size_changed
- Product size/variant changedlce:actions.product_fulfillment_type_changed
- Delivery method changedlce:actions.cart_opened
- Cart displayedlce:actions.cart_closed
- Cart hiddenlce:actions.cart_updated
- Cart contents changedlce:actions.cart_item_added
- Item addedlce:actions.cart_item_removed
- Item removedlce:actions.cart_reset
- Cart clearedlce:actions.checkout_opened
- Checkout startedlce:actions.checkout_closed
- Checkout abandonedlce:actions.checkout_submit_started
- Order submission beganlce:actions.checkout_submit_completed
- Order completed successfullylce:actions.checkout_submit_failed
- Order failedlce:actions.checkout_customer_information_updated
- Customer info enteredlce:actions.checkout_billing_information_updated
- Billing info enteredlce:actions.address_updated
- Address information changedlce:actions.address_cleared
- Address removedSee docs/EVENTS.md
for complete event reference with implementation examples.
Configure the SDK when initializing:
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 */ }
});
production
: Live environment for customer-facing sitesstaging
: Pre-production testing environmentdevelopment
: Development environment with additional debugginglocal
: Local development environmentWhen using auto-initialization, configure via data attributes:
data-liquid-commerce-elements
: Required flag to enable auto-initdata-token
: Your API key (required)data-env
: Environment (defaults to production)data-cart-id
: Container ID for cart buttondata-enable-debugging
: Enable debugging modedata-container-X
/ data-product-X
: Product mapping pairsCustomize the appearance of SDK components using the theme system:
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:
// Update themes in real-time (builder mode only)
await client.builder.updateComponentGlobalConfigs({
colors: { primary: '#ff6b6b' }
});
await client.builder.updateProductComponent({
layout: { imagePosition: 'right' }
});
Route API requests through your server to avoid ad blockers:
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
for complete proxy setup guide with Next.js examples.
For detailed guides and advanced usage:
docs/ACTIONS.md
- Complete actions reference with business use casesdocs/EVENTS.md
- Events guide with implementation examplesdocs/BROWSER_SUPPORT.md
- Detailed browser compatibilitydocs/PROXY.md
- Proxy configuration for ad blocker avoidanceThis project uses Semantic Versioning. The SDK is available in two environments:
beta
https://assets-elements.liquidcommerce.us/all/beta/
main
https://assets-elements.liquidcommerce.us/all/
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)
The SDK includes ready-to-use demo pages in the demo/
folder that showcase different implementation approaches:
demo/simple.html
)Demonstrates auto-initialization using data attributes - the easiest way to get started:
<!-- 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:
Best for: Quick prototyping, simple integrations, getting familiar with the SDK
demo/advanced.html
)Demonstrates programmatic initialization for full control:
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:
Best for: Complex integrations, custom workflows, theme customization, production implementations
development
, staging
, production
)The demos use local UMD builds (../umd/elements.js
) but can be easily switched to CDN URLs for testing.
For SDK development and maintenance, the following npm/pnpm scripts are available:
build
- Production build
pnpm run build
dist/index.esm.js
(ESM) + umd/elements.js
(UMD)build:dev
- Development build
pnpm run build:dev
dev
- Development with watch mode
pnpm run dev
build:dev
but watches for file changeslint
- Lint and auto-fix code
pnpm run lint
format
- Format code
pnpm run format
biome.json
check
- Combined linting and formatting
pnpm run check
fl
- Format, lint, and build (Fast Loop)
pnpm run fl
check
+ build:dev
clean
- Clean build outputs
pnpm run clean
dist/
and umd/
directoriesclean:hard
- Complete reset
pnpm run clean:hard
node_modules/
pnpm install
changelog
- Generate changelog
pnpm run changelog
CHANGELOG.md
from conventional commitsThe build system uses Rollup with different configurations:
dist/index.esm.js
)umd/elements.js
)window.LiquidCommerceElements
<script>
tagsDevelopment Workflow:
# Start development
pnpm run dev
# Before committing
pnpm run fl
Release Workflow:
# Clean and build for release
pnpm run clean:hard
# Generate changelog
pnpm run changelog
# Build is run automatically on publish
Troubleshooting:
# If builds are failing
pnpm run clean:hard
# For code quality issues
pnpm run check
If you need help with your API key, environment selection, or implementation, contact your LiquidCommerce representative.
Built with โค๏ธ by the LiquidCommerce Team
Actions Reference โข Events Guide โข Browser Support โข Proxy Setup
FAQs
LiquidCommerce Elements SDK
The npm package @liquidcommerce/elements-sdk receives a total of 1,347 weekly downloads. As such, @liquidcommerce/elements-sdk popularity was classified as popular.
We found that @liquidcommerce/elements-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.