konfigra Embed SDK
Add the 3D configurator to your website with a single line of JavaScript
The konfigra Embed SDK lets you integrate an iframe-based 3D product customizer directly into your website. Your customers can configure products, save their designs, and continue to checkout — without ever leaving your store.
One-line setup
Integrate in under a minute with a script tag
PostMessage API
Control colors, products, and capture screenshots
E-commerce ready
Modal mode + design URL injected into your cart form
https://{your-store}.konfigra.com/embed/konfigra-embed.js
Quick Start
Add the script tag to your page — that's it.
<!-- 1. Widget container -->
<div id="konfigra-widget"></div>
<!-- 2. SDK script -->
<script
src="https://{your-store}.konfigra.com/embed/konfigra-embed.js"
data-container="#konfigra-widget"
data-product="5"
data-mode="simple">
</script>
Replace 5 with a real product ID from your store.
Script Tag
No JavaScript knowledge required. All options are set via HTML attributes.
<div id="konfigra-widget"></div>
<script
src="https://{your-store}.konfigra.com/embed/konfigra-embed.js"
data-container="#konfigra-widget"
data-product="5"
data-template="12"
data-mode="simple"
data-height="600px"
data-width="100%">
</script>
| Attribute | Required | Description |
|---|---|---|
data-container |
Yes | CSS selector for the widget container (e.g. #widget) |
data-product |
No | Product ID to load automatically. Omit to show the product list. |
data-template |
No | Template ID to pre-select |
data-mode |
No | simple (default) or full for the complete studio experience |
data-height |
No | iframe height — default: 600px |
data-width |
No | iframe width — default: 100% |
Programmatic
Load the SDK first, then initialize it with JavaScript. Gives full access to event listeners and control methods.
<script src="https://{your-store}.konfigra.com/embed/konfigra-embed.js"></script>
<div id="konfigra-widget"></div>
<script>
const embed = konfigraEmbed.init({
container: '#konfigra-widget',
productId: 5, // optional: open a specific product
templateId: 12, // optional: pre-select a template
mode: 'simple', // 'simple' | 'full'
height: '600px',
on: {
'konfigra:ready': () => {
console.log('Studio is ready');
},
'konfigra:color-changed': ({ layerId, color, allColors }) => {
console.log('Color changed:', layerId, '→', color);
},
'konfigra:design-saved': ({ designId, salt, shareUrl }) => {
console.log('Design saved:', shareUrl);
},
}
});
</script>
productId is omitted, the studio opens the product list and the user picks one.
Pass a product ID to jump straight to that product.
Modal
The studio opens in a centered overlay when the user clicks a button. Ideal for product detail pages.
<script src="https://{your-store}.konfigra.com/embed/konfigra-embed.js"></script>
<button id="customize-btn">Customize Product</button>
<script>
const embed = konfigraEmbed.init({
mode: 'modal', // no container needed — SDK builds the overlay
productId: 5,
on: {
'konfigra:design-saved': ({ designId, salt, shareUrl }) => {
document.querySelector('[name="konfigra_design_url"]').value = shareUrl;
embed.close();
}
}
});
document.querySelector('#customize-btn').addEventListener('click', () => embed.open());
</script>
The SDK automatically creates the backdrop overlay and a close button.
Clicking the backdrop or calling embed.close() dismisses it.
init() Options
All parameters accepted by konfigraEmbed.init(opts).
| Option | Type | Default | Description |
|---|---|---|---|
container |
string | Element | — | CSS selector or DOM element. Optional when mode:'modal'. |
mode |
string | 'simple' |
simple — color-only lite studiofull — full studio experiencemodal — studio inside a popup overlay
|
productId |
number | null |
Product to open directly. Omit to show the product list. |
templateId |
number | null |
Template to pre-select. Used together with productId. |
height |
string | '600px' |
iframe height (any CSS unit) |
width |
string | '100%' |
iframe width |
on |
object | {} |
Shorthand event listeners: { 'konfigra:ready': fn, ... } |
Control Methods
Called on the object returned by konfigraEmbed.init().
embed.setColor(layerId, color)
Color
Changes the color of a UV layer. Layer IDs are defined in your product templates. Accepts any CSS color value.
embed.setColor('body', '#ff0000');
embed.setColor('collar', 'rgb(0, 128, 0)');
embed.setColor('sleeve', 'navy');
// Method chaining
embed.setColor('body', '#3b82f6')
.setColor('collar', '#1e293b');
embed.setProduct(productId, templateId?)
Product
Switches the displayed product and/or template. Useful for letting users switch between variants without reloading the widget.
embed.setProduct(7); // switch product only
embed.setProduct(7, 23); // switch product + template
embed.resetColors()
Color
Resets all UV layer colors to the template defaults.
embed.getScreenshot() → Promise<string>
Visual
Captures the current 3D view as a PNG. Returns a base64 data URI. Rejects after 10 seconds if no response arrives.
embed.getScreenshot().then(dataUri => {
document.querySelector('#preview').src = dataUri;
}).catch(err => {
console.error('Screenshot failed:', err.message);
});
embed.on(event, fn) / embed.off(event, fn)
Add or remove an event listener after initialization.
const handler = ({ layerId, color }) => console.log(layerId, color);
embed.on('konfigra:color-changed', handler);
// later…
embed.off('konfigra:color-changed', handler);
embed.open() / embed.close()
Modal
Open or close the overlay. Only works when mode: 'modal'.
embed.destroy()
Removes the iframe from the DOM and cleans up all event listeners. Call this when unmounting the widget in single-page applications.
Events
The studio sends messages to your parent page on specific user actions.
Listen via the on option or embed.on().
const embed = konfigraEmbed.init({
container: '#widget',
productId: 5,
on: {
'konfigra:ready': () => console.log('Studio ready'),
'konfigra:product-loaded': (payload) => console.log('Product loaded', payload),
'konfigra:color-changed': (payload) => console.log('Color changed', payload),
'konfigra:design-saved': (payload) => console.log('Design saved', payload),
}
});
| Event | Payload | Description |
|---|---|---|
konfigra:ready |
— | The iframe has fully loaded and the studio is ready to use |
konfigra:product-loaded |
{ productId, templateId } |
A 3D model has been loaded and rendered |
konfigra:color-changed |
{ layerId, color, allColors } |
The user changed a layer color.
allColors is a map of all active colors: { layerId: color }
|
konfigra:design-saved |
{ designId, salt, shareUrl } |
The user clicked Save. Use shareUrl to reload the design later.
|
konfigra:screenshot |
{ requestId, imageData } |
Internal — handled automatically by getScreenshot() |
PostMessage API (advanced)
Communicate with the studio iframe directly via window.postMessage —
useful when building custom wrappers or framework integrations.
Parent → iframe (commands)
| type | payload | Description |
|---|---|---|
konfigra:set-color | { layerId, color } | Change a layer color |
konfigra:set-product | { productId, templateId? } | Switch product/template |
konfigra:reset-colors | — | Reset all colors |
konfigra:get-screenshot | { requestId } | Request a screenshot — response arrives as konfigra:screenshot |
iframe → Parent (events)
| type | payload |
|---|---|
konfigra:ready | — |
konfigra:product-loaded | { productId, templateId } |
konfigra:color-changed | { layerId, color, allColors } |
konfigra:design-saved | { designId, salt, shareUrl } |
konfigra:screenshot | { requestId, imageData } |
const iframe = document.querySelector('iframe');
// Send a command
iframe.contentWindow.postMessage({
type: 'konfigra:set-color',
payload: { layerId: 'body', color: '#3b82f6' }
}, '*');
// Listen for events
window.addEventListener('message', (event) => {
if (event.source !== iframe.contentWindow) return;
const { type, payload } = event.data;
if (type === 'konfigra:design-saved') {
console.log('Design URL:', payload.shareUrl);
}
});
E-commerce Flow
The user customizes a product in the modal, saves their design, and the share URL is automatically written into a hidden input so it travels with the cart form.
<form id="cart-form" method="POST" action="/cart/add">
<input type="hidden" name="product_id" value="5">
<!-- konfigra writes the design URL here automatically -->
<input type="hidden" name="konfigra_design_url" id="design-url">
<input type="hidden" name="konfigra_design_id" id="design-id">
<button type="button" id="customize-btn">Customize Product</button>
<button type="submit" id="cart-btn" disabled>Add to Cart</button>
</form>
<script src="https://{your-store}.konfigra.com/embed/konfigra-embed.js"></script>
<script>
const embed = konfigraEmbed.init({
mode: 'modal',
productId: 5,
on: {
'konfigra:ready': () => {
document.querySelector('#customize-btn').disabled = false;
},
'konfigra:design-saved': ({ designId, salt, shareUrl }) => {
document.querySelector('#design-url').value = shareUrl;
document.querySelector('#design-id').value = designId;
embed.close();
const btn = document.querySelector('#cart-btn');
btn.disabled = false;
btn.textContent = 'Add to Cart ✓';
}
}
});
document.querySelector('#customize-btn').addEventListener('click', () => embed.open());
</script>
konfigra_design_url
is stored with the order. Click the URL from your admin panel to view exactly what the customer designed.
Full Example
Color panel synchronized with the studio + screenshot capture. Copy, paste, and run.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>konfigra Embed Example</title>
<style>
* { box-sizing: border-box; }
body { font-family: sans-serif; margin: 0; background: #f8fafc; }
.container { max-width: 1100px; margin: 2rem auto; padding: 0 1rem; }
h1 { font-size: 1.5rem; font-weight: 700; color: #1e293b; margin-bottom: 1rem; }
.toolbar {
display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center;
background: #fff; border: 1px solid #e2e8f0; border-radius: 12px;
padding: 0.75rem 1rem; margin-bottom: 1rem;
}
.toolbar label { font-size: 0.875rem; color: #64748b; display: flex; align-items: center; gap: 0.4rem; }
input[type=color] { width: 32px; height: 32px; border: none; border-radius: 6px; cursor: pointer; }
.btn {
padding: 0.45rem 0.9rem; border: none; border-radius: 8px; cursor: pointer;
font-size: 0.875rem; font-weight: 500; background: #6366f1; color: #fff;
}
.btn-outline { background: transparent; border: 1px solid #e2e8f0; color: #64748b; }
#status { font-size: 0.8rem; color: #94a3b8; margin-left: auto; }
#widget { border-radius: 16px; overflow: hidden; box-shadow: 0 4px 24px rgba(0,0,0,.08); }
#preview { margin-top: 1rem; max-width: 300px; border-radius: 12px; display: none;
box-shadow: 0 4px 20px rgba(0,0,0,.12); }
</style>
</head>
<body>
<div class="container">
<h1>Product Customizer</h1>
<div class="toolbar">
<label>
Body
<input type="color" id="c-body" value="#3b82f6"
oninput="embed.setColor('body', this.value)">
</label>
<label>
Sleeve
<input type="color" id="c-sleeve" value="#1e293b"
oninput="embed.setColor('sleeve', this.value)">
</label>
<button class="btn btn-outline" onclick="embed.resetColors()">Reset</button>
<button class="btn" onclick="screenshot()">Screenshot</button>
<span id="status">Loading…</span>
</div>
<div id="widget"></div>
<img id="preview" alt="Design preview">
</div>
<script src="https://{your-store}.konfigra.com/embed/konfigra-embed.js"></script>
<script>
const embed = konfigraEmbed.init({
container: '#widget',
productId: 5,
mode: 'simple',
height: '580px',
on: {
'konfigra:ready': () => {
document.querySelector('#status').textContent = 'Ready ✓';
},
'konfigra:color-changed': ({ layerId, color }) => {
const el = document.querySelector('#c-' + layerId);
if (el) el.value = color;
},
'konfigra:design-saved': ({ shareUrl }) => {
alert('Design saved!\n' + shareUrl);
}
}
});
function screenshot() {
document.querySelector('#status').textContent = 'Capturing…';
embed.getScreenshot().then(dataUri => {
const img = document.querySelector('#preview');
img.src = dataUri;
img.style.display = 'block';
document.querySelector('#status').textContent = 'Ready ✓';
});
}
</script>
</body>
</html>