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%"
data-lang="auto">
</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% |
data-lang |
No | Studio language, e.g. en, tr, de, or auto to follow your page's <html lang>. See Studio Language. |
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',
lang: 'auto', // optional: 'en' | 'tr' | 'de' | 'auto'
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 |
lang |
string | null |
Studio language code (en, tr, de).
'auto' uses the first two letters of your page's <html lang>.
Omit to use your store's default studio language.
|
on |
object | {} |
Shorthand event listeners: { 'konfigra:ready': fn, ... } |
Studio Language
Open the studio in the same language as your page with lang (or data-lang).
// Fixed language
konfigraEmbed.init({ container: '#konfigra-widget', productId: 5, lang: 'de' });
// Follow the host page: <html lang="tr-TR"> opens the studio in Turkish
konfigraEmbed.init({ container: '#konfigra-widget', productId: 5, lang: 'auto' });
- The code is sent to the studio as
?lang=<code>. Supported codes:en,tr,de. 'auto'takes the first two letters ofdocument.documentElement.lang. If your page has nolangattribute, nothing is sent.- Only languages enabled for your store in the studio settings are honoured. Any other value is ignored and your store's default studio language is used, so an unsupported page language never breaks the widget.
- The language is fixed when the widget is created. To switch it, call
embed.destroy()andinit()again with the newlang.
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>