SDK API
The SDK exposes a single THGVTO class plus a few static DOM helpers. Everything
else is a product handle — you create one per product and call generate() or
getImage() on it.
Loading the SDK
Section titled “Loading the SDK”The script tag reads data-api-url and data-api-key as defaults, so you can
configure once and not repeat it in JavaScript:
<script src="http://static.thcdn.com/vto-sdk.js" data-api-url="https://api-nonprod.thg.dev/agentic-commerce/v1/vto" data-api-key="your-api-key"></script>You can also import the bundle as an ES module and pass apiUrl / apiKey
directly to the constructor.
Creating a THGVTO instance
Section titled “Creating a THGVTO instance”At minimum:
const vto = new THGVTO();With a theme:
const vto = new THGVTO({ theme: { primaryColor: '#003942', primaryTextColor: '#fff' },});All options are optional — defaults match the “invisible on any storefront” aesthetic. Common ones:
| Option | Default | What it does |
|--------|---------|--------------|
| theme | — | Modal CSS tokens (primaryColor, buttonRadius, fontFamily, …) |
| content | — | Overrides for modal copy (modalTitle, uploadHint, disclaimerText, …) |
| watermark | off | Brand watermark on downloaded/shared images |
| consent | both true | GDPR consent for photo processing and storage |
| showAddToCart / showWishlist | false | Actions on the result view |
| modelsEnabled | false | Offer predefined models alongside user upload |
| qrEnabled | false | QR code for mobile upload from desktop |
See the Configuration Reference for the full list and TypeScript types.
Working with products
Section titled “Working with products”vto.getProduct() returns a THGVTOProduct handle. Handles are cached by
product image URL, so calling getProduct() repeatedly with the same image
returns the same instance.
const product = vto.getProduct({ image: 'https://cdn.example.com/products/shirt.jpg', // required url: window.location.href, // required title: 'Blue Oxford Shirt', price: '£35.00', id: 'SKU-12345',});product.generate(options?)
Section titled “product.generate(options?)”Opens the modal, walks the user through upload/generation, resolves with the
result URL — or null if the user closed the modal.
const imageUrl = await product.generate();if (imageUrl) { // inject imageUrl into your gallery}Pass { mode: 'direct' } to skip the modal when the user already has a photo
uploaded. Falls back to the modal if no photo exists or direct generation fails.
await product.generate({ mode: 'direct' });product.getImage()
Section titled “product.getImage()”Returns a cached try-on URL for this product (keyed on the uploaded person
photo), or null if nothing is cached. Use this on page load to show a result
before the user even clicks.
const cached = await product.getImage();if (cached) injectResult(cached);DOM helpers
Section titled “DOM helpers”The SDK ships four static helpers on THGVTO that make it easy to inject
results into any storefront’s gallery without touching the SDK’s internals.
THGVTO.clone(templateEl, imageUrl, badgeLabel?, productImage?)
Section titled “THGVTO.clone(templateEl, imageUrl, badgeLabel?, productImage?)”Clones a gallery slide (the first child of your carousel, say), swaps every
<img> src to the try-on URL, strips buttons, and stamps a badge. Returns the
clone — you decide where to insert it.
const carousel = document.getElementById('product-gallery');const slide = THGVTO.clone( carousel.firstElementChild, imageUrl, 'TRY-ON', product.image,);carousel.insertBefore(slide, carousel.firstElementChild);The cloned element gets data-vto-result (and data-vto-product-image when
you pass productImage) so update() and clear() can find it later.
THGVTO.update(imageUrl, productImage?)
Section titled “THGVTO.update(imageUrl, productImage?)”Updates the src of every <img> inside existing result elements. Pass
productImage to scope to a single product. Returns true if any elements
were found.
if (!THGVTO.update(newImageUrl, product.image)) { // no existing result — inject a new one with clone()}THGVTO.clear(productImage?)
Section titled “THGVTO.clear(productImage?)”Removes result elements from the DOM. Pass productImage to scope to a single product.
// User changed variant — drop the old try-onwindow.addEventListener('variant-change', () => { THGVTO.clear();});THGVTO.watch(el, callback, debounceMs?)
Section titled “THGVTO.watch(el, callback, debounceMs?)”Debounced MutationObserver — useful when your gallery re-renders on
variant changes and you need to re-inject the result after the DOM settles.
const galleryRoot = document.getElementById('pdp-gallery-container');const stop = THGVTO.watch(galleryRoot, () => { if (document.querySelector('[data-vto-result]')) return; updateTryOnImage();});// stop() to disconnectConsent
Section titled “Consent”Update consent state at runtime (e.g. when a cookie banner is accepted):
vto.updateConsent({ photoProcessing: true, photoStorage: true });See the GDPR Consent guide for details.
Full example — PDP integration
Section titled “Full example — PDP integration”const vto = new THGVTO({ theme: { primaryColor: '#003942', primaryTextColor: '#FDFCFB' },});
function getCurrentProduct() { const v = window.__CURRENTVARIANT__; return vto.getProduct({ title: v.title, image: v.images[0].original, url: window.location.href, id: v.sku, });}
function injectResult(imageUrl) { const productImage = getCurrentProduct().image; if (THGVTO.update(imageUrl, productImage)) return;
const carousel = document.getElementById('gallery-carousel'); const slide = THGVTO.clone(carousel.firstElementChild, imageUrl, 'TRY-ON', productImage); carousel.insertBefore(slide, carousel.firstElementChild);}
let product = getCurrentProduct();
// Show cached result on loadproduct.getImage().then(img => { if (img) injectResult(img); });
// Variant changes — drop old result, re-bind productwindow.addEventListener('variant-change', () => { THGVTO.clear(); product = getCurrentProduct();});
// Re-inject after gallery re-rendersconst galleryRoot = document.getElementById('pdp-gallery-container');THGVTO.watch(galleryRoot, () => { if (document.querySelector('[data-vto-result]')) return; product = getCurrentProduct(); product.getImage().then(img => { if (img) injectResult(img); });});
// Trigger buttondocument.getElementById('vto-trigger').addEventListener('click', async () => { const result = await product.generate(); if (result) injectResult(result);});