IdealFactory Developer Docs

JavaScript reference

https://api.idealfactory.com/embed/v1/customiser.js is the whole client integration. Loading it mounts the Customiser into every element carrying data-idealfactory-customiser — including elements added later, so modals and SPA navigation need no re-initialisation — and reports back through bubbling DOM events. It owns the session lifecycle end to end: you never handle tokens, URLs, or expiry.

Attributes

There is no JavaScript initialisation — everything is configured with attributes on the mount element:

Attribute Required Meaning
data-idealfactory-customiser yes Marks the element the Customiser fills. Give it real size — fullscreen is best.
data-embed-key yes Your public embed key. Only works from your registered domains.
data-sku no Your product SKU or reference — resolved to our product through the mapping on your storefront page (supplier SKUs need no mapping).
data-product no Our product id, if you'd rather name it directly.
data-design-version no A design id you stored earlier — opens it for re-editing.

Give at most one of data-sku, data-product, data-design-version. Give none and the Customiser opens on a product selection page — customers pick from your mapped products (or everything you sell, if nothing is mapped) and go straight into designing it. This needs "customers choose the product inside" enabled in your storefront settings; otherwise a snippet without a product is refused. | data-customer-token | no | Identity claim for your logged-in customer — see Customer identity. | | data-api-base | no | Defaults to the origin the script was loaded from. Only for staging setups. | | data-debug | no | Console-logs the message traffic. |

Mounting & unmounting

There is no lifecycle to manage. An element mounts when it appears — on page load, or added later by a modal or SPA navigation — and tears itself down when it leaves the DOM: the iframe and every listener are released automatically. So an "edit design" modal is exactly two operations: insert the element to open, remove it to close. Nothing to initialise, nothing to destroy, nothing leaks.

Events

All events bubble, so one document.addEventListener covers every Customiser on the page; listen on the element itself if you mount several and need to tell them apart.

customiser:design-ready

Fires after every successful finish. This is your integration point.

document.addEventListener('customiser:design-ready', function (e) {
  e.detail.design_id          // stable across re-edits of one design
  e.detail.design_version_id  // THIS saved version — store it on your cart line
  e.detail.thumbnails           // raw base64 JPEG previews, in view order
});

Always keep the latest design_version_id you receive — a customer can finish, keep editing, and finish again; each finish returns a new id and your cart line should point at the newest one. (The script already chains versions correctly internally; you only ever store the latest.)

Thumbnails carry no data: prefix — add one to display them: 'data:image/jpeg;base64,' + e.detail.thumbnails[0].

customiser:back

The customer clicked the Customiser's back/exit control. Close your overlay or navigate back to the product page.

customiser:error

document.addEventListener('customiser:error', function (e) {
  e.detail.stage;   // 'session' | 'mount' | 'save'
  e.detail.detail;  // Error or string for your logs
});
stage Meaning Sensible handling
session The session could not be created (bad key, unregistered domain, unavailable product) Hide the Customiser, show a generic error; check key / domain / product id
mount The mount element was unusable Fix the markup
save A finish could not be saved after retrying Ask the customer to try finishing again — their work is still in the Customiser

Errors are never silently swallowed: everything lands on this event.

Session lifecycle (what the script does for you)

Versioning & caching

The v1 in the URL is the compatibility contract: everything documented here holds for as long as /embed/v1/customiser.js exists.

Don't self-host or copy the file — you'd freeze yourself out of fixes.

Advanced: programmatic mounting

Everything above needs no JavaScript API, and dynamically inserted data-idealfactory-customiser elements mount automatically — so most shops never need this section. The exception is a server-created session (your backend called POST /v1/shop/sessions itself with the API token, for example to attach external_ref directly):

IdealFactory.customiser({
  container: 'customiser-container',      // element or id
  session: sessionFromYourServer,     // the response's `data` object
  onDesignReady: function (design) { /* same payload as the event */ },
  onBack: function () {},
  onError: function (stage, detail) {},
});

Callbacks fire in addition to the DOM events. In this mode the script does not self-renew (it holds no embed key): an expired save surfaces as an error and your code fetches a fresh session. Prefer the declarative embed key plus, for identity, a customer token — renewal then stays automatic.