Getting Started
The SDK is loaded automatically on every storefront page — you do not install it from npm or add a <script> tag yourself. This guide shows how to initialize it and make your first request.
What the platform injects
When a page renders, SitePack injects the SDK bundle and a small block of global configuration:
<script src="/js/sitepack_sdk.js"></script>
<script>
window.SITEPACK_CLIENT_ID = '…'; // request-binding hash
window.SITEPACK_CSRF_TOKEN = '…'; // CSRF token for /api/sdk/*
window.SITEPACK_SITE_UUID = '…'; // the current site
window.SITEPACK_DOMAIN = 'https://example.com';
</script>
It also creates a shared, ready-to-use instance for core theme code:
window.coreThemeSdk = new SitePackSDK({ type: 'theme', id: 'theme-core' });
These are provided by the server for the current visitor and site. The SDK constructor reads them and throws if any is missing. Overwriting them will break request signing.
Creating your own instance
Create a named instance so your requests are attributed to your theme or app:
// In a theme
const sdk = new SitePackSDK({ type: 'theme', id: 'my-theme' });
// In an app
const sdk = new SitePackSDK({ type: 'app', id: 'my-app' });
| Option | Values | Default | Purpose |
|---|---|---|---|
type | 'theme' | 'app' | 'theme' | Who is making the call (sent as the initiator type). |
id | non-empty string | 'default' | Your theme or app identifier, used for attribution and logging. |
Multiple instances can coexist on one page — they share the same request queue, rate-limit budget, and cart-sync channel.
Your first call
Every network method returns a Promise. Always handle failures:
const sdk = new SitePackSDK({ type: 'theme', id: 'my-theme' });
try {
const cart = await sdk.ecommerce.getCart();
console.log(`Cart has ${cart.total_products} product(s).`);
} catch (error) {
// Network error, validation error, or a 429 rate-limit response
console.error('SDK call failed:', error.message);
}
Reacting to cart changes
Cart-mutating calls (addToCart, updateCartQuantity, clearCart) emit a DOM event on window, both in the current tab and — via BroadcastChannel — in every other open tab and SDK instance:
window.addEventListener('sitepack:cart:updated', (event) => {
const { cart, source } = event.detail; // source: 'local' | 'sync'
renderCartBadge(cart.total_products);
});
A minimal working example
document.addEventListener('DOMContentLoaded', async () => {
const sdk = new SitePackSDK({ type: 'theme', id: 'my-theme' });
// Keep a cart badge in sync across tabs
window.addEventListener('sitepack:cart:updated', (e) => {
document.querySelector('#cart-count').textContent = e.detail.cart.total_products;
});
// Wire up add-to-cart buttons
document.querySelectorAll('[data-add-to-cart]').forEach((btn) => {
btn.addEventListener('click', async () => {
try {
await sdk.ecommerce.addToCart(btn.dataset.addToCart, 1);
} catch (err) {
sdk.ui.notify('Could not add product to cart.', 'error');
}
});
});
});
Rate limits at a glance
There are two layers of rate limiting — see Security & Rate Limiting for the full picture:
- Client-side — a shared token bucket (15 requests, refilling over 10 seconds). Exceeding it throws
Too Many Requests (Client-side Rate Limit)before any network call is made. - Server-side — a per-IP limiter on
/api/sdk/*(15 requests / 10 seconds). Exceeding it returns HTTP429, which the SDK surfaces as a rejected promise.
Batch UI updates, debounce search-as-you-type, and cache results you can reuse (the SDK already caches the cart and order-capability lookups). Don't poll in tight loops.
Next steps
- Ecommerce — the largest module: products, cart, checkout.
- Security & Rate Limiting — CSRF, limits, and safe-usage rules.
- API Reference — every method and its endpoint.