Programmatic control of the 3D configurator for headless / React / Vue / Next.js apps. The SDK mounts the configurator in an iframe, resolves your shop SKUs to 3D products, and re-emits every widget event to your code.
embed.js (widget) | sdk.js (this page) | |
|---|---|---|
| Setup | One <script> tag, auto-detects the product on the page | You instantiate a class and decide when/where to mount |
| Best for | Shopify, WooCommerce, CMS pages — turnkey | SPAs, custom carts, dynamic product switching |
| Control | Data attributes + a cart callback | Full API: mount, on/off, setProduct, destroy |
If you just want the configurator on a product page with zero code, use the embed widget. If you build your own frontend and cart, use the SDK — the custom site guide shows a complete integration.
The SDK is a standard ES module served from our CDN — no npm package, no build step required:
import { PrintWearAI } from 'https://printwearai.com/sdk.js';
Loaded via a <script type="module"> tag, the class is also exposed as window.PrintWearAI for non-module code.
const pwai = new PrintWearAI({ embedKey: 'fk_xxxx' });
| Option | Type | Description |
|---|---|---|
embedKey | string | Required. Your public fk_ key (workspace → Integration). The constructor throws if missing. |
origin | string | Base URL of the platform. Defaults to https://printwearai.com. |
Never put your secret sk_ key in frontend code — the SDK only ever needs the public embed key. See Public REST API.
mount(selector, options)Mounts the configurator iframe inside a container (CSS selector or DOM element). Returns a promise resolving to the instance. The container's previous content is replaced.
// By catalog slug
await pwai.mount('#configurator', { product: 'tshirt-classic-v1' });
// By shop SKU — resolved automatically via GET /api/resolve
await pwai.mount('#configurator', { sku: 'MY-SKU-42' });
| Option | Description |
|---|---|
product | Product slug from your PrintWearAI catalog. |
sku | Your shop's SKU. Resolved through /api/resolve; mount throws if no 3D product is linked to it. |
productId | Your shop's product ID (alternative to sku, same resolution). |
config | ID of a saved configuration to preload. |
height | Initial minimum iframe height in px. Default 700. The iframe then auto-resizes (never below 480 px). |
If you pass neither product nor sku/productId, the widget opens on its product picker.
on(event, fn) / off(event, fn)The widget posts messages to the parent page; the SDK re-emits each message under its type. Both methods are chainable.
| Event | Payload | When |
|---|---|---|
add_to_cart | Product info (incl. product.external_sku), quantity, pricing | Customer clicks "Add to cart" — wire this to your own cart. |
resize | { height } | Widget content height changed. The SDK already resizes the iframe for you; listen only if you need the value. |
redirect | { url } | The widget asks the host page to navigate (e.g. checkout). |
pwai.on('add_to_cart', (payload) => {
addToMyCart({ sku: payload.product.external_sku, qty: payload.quantity });
});
pwai.on('redirect', ({ url }) => { window.location = url; });
Listener exceptions are caught and logged to the console — one faulty handler will not break the others.
setProduct(slug)Switches the mounted configurator to another catalog product without reloading the iframe:
pwai.setProduct('sweat-zip-v2');
destroy()Removes the message listener, empties the container and clears all event listeners. Call it when your component unmounts (e.g. in a React useEffect cleanup); you can then reuse the instance with a new mount().
<div id="configurator"></div>
<script type="module">
import { PrintWearAI } from 'https://printwearai.com/sdk.js';
const pwai = new PrintWearAI({ embedKey: 'fk_xxxx' });
await pwai.mount('#configurator', { sku: 'MY-SKU-42', height: 760 });
pwai
.on('add_to_cart', ({ product, quantity }) => {
myCart.add(product.external_sku, quantity);
})
.on('redirect', ({ url }) => { window.location = url; });
// later: pwai.setProduct('shorts-pro-v1'); pwai.destroy();
</script>
/resolve, /embed/bootstrap…).