Adding AI Try-On to your Wix store
How to add the Vizbl AI Try-On button to Wix Stores product pages, including sites built in Wix Harmony.
You’ll paste our code into your site once, and every product page gets a Try on button filled in with that product’s name, image, price, and link. There are two ways to do it:
- Custom element — for Wix Editor and Wix Studio. You place the button on the product page yourself.
- Custom code — for any Wix editor, including Wix Harmony. The button floats in the corner of the screen on product pages.
Before you start
In your AI Try-On dashboard, create a widget for the type of product you sell and add your store’s domain.
In the Your widgets block, open the install window of that widget. In the button code, copy two values:
data-neurodyn-ai-try-on-product-type— the widget type, likefull-bodyorupper-body;data-neurodyn-ai-try-on-api-key— the widget’s key.
Each widget type has its own key, and they work only as a pair.
Adding an AI Try-On widget to your website
Option 1: Custom element
Wix runs custom elements only on sites with a Premium plan, a connected domain, and no Wix ads.
1. Open your site in the editor. In Wix Editor, click Dev Mode in the top bar, then Turn on Dev Mode. In Wix Studio, skip this step.
2. Click Pages & Menu, then Store Pages, then Product Page.
3. Add a custom element:
- Wix Editor: click Add Elements, then Embed Code, then Custom Element.
- Wix Studio: click Add Elements, then Embed & Social, then Custom Element.
Drag it to where you want the button. The element sits on the page next to the product block, not inside it, so place it under or beside the block.
4. Select the element, click Choose Source, and select Velo file. Wix creates a sample file wix-default-custom-element.js in your site’s public files.
5. Open that file in the code panel, delete everything in it, and paste this code:
// ===== Settings: change these =====
// Copy both from the same widget's install window in your AI Try-On dashboard
const PRODUCT_TYPE = 'full-body'; // value of data-neurodyn-ai-try-on-product-type
const API_KEY = 'PASTE_WIDGET_KEY_HERE'; // value of data-neurodyn-ai-try-on-api-key
const BUTTON_TEXT = 'Try on';
const BUTTON_COLOR = '#000000';
const TEXT_COLOR = '#ffffff';
// Product name, image, price, and link are filled in automatically from each product page
// ===== Don't change anything below this line =====
const SCRIPT_SRC = 'https://cdn.neurodyn.ai/@neurodyn/ai-try-on/dist/ai-try-on.embed.min.js';
const PREFIX = 'data-neurodyn-ai-try-on-';
function loadScript() {
if (document.querySelector(`script[src="${SCRIPT_SRC}"]`)) return;
const script = document.createElement('script');
script.src = SCRIPT_SRC;
script.defer = true;
document.head.appendChild(script);
}
function pickImage(image) {
const first = Array.isArray(image) ? image[0] : image;
if (!first) return '';
return typeof first === 'string' ? first : first.contentUrl || first.url || '';
}
function formatPrice(amount, currency) {
if (amount == null || amount === '') return '';
try {
return new Intl.NumberFormat(document.documentElement.lang || undefined, {
style: 'currency',
currency,
}).format(amount);
} catch (e) {
return String(amount);
}
}
function meta(name) {
const tag = document.querySelector(`meta[property="${name}"], meta[name="${name}"]`);
return tag ? tag.content : '';
}
function findProduct() {
for (const node of document.querySelectorAll('script[type="application/ld+json"]')) {
let data;
try {
data = JSON.parse(node.textContent);
} catch (e) {
continue;
}
const items = [].concat(data && data['@graph'] ? data['@graph'] : data);
const product = items.find((item) => item && [].concat(item['@type']).includes('Product'));
if (product) {
const offers = product.offers || product.Offers;
const offer = Array.isArray(offers) ? offers[0] : offers || {};
return {
name: product.name,
image: pickImage(product.image),
price: formatPrice(offer.price != null ? offer.price : offer.lowPrice, offer.priceCurrency),
url: product.url || offer.url || location.href,
};
}
}
return {
name: meta('og:title'),
image: meta('og:image'),
price: formatPrice(meta('product:price:amount'), meta('product:price:currency')),
url: meta('og:url') || location.href,
};
}
class VizblTryOn extends HTMLElement {
connectedCallback() {
this.render();
loadScript();
this.lastUrl = location.href;
this.timer = setInterval(() => {
if (location.href === this.lastUrl) return;
this.lastUrl = location.href;
setTimeout(() => this.render(), 1000);
}, 500);
}
disconnectedCallback() {
clearInterval(this.timer);
}
render() {
if (!this.button) {
this.button = document.createElement('button');
this.button.type = 'button';
this.button.textContent = BUTTON_TEXT;
this.button.setAttribute(PREFIX + 'dialog', '');
this.button.setAttribute(PREFIX + 'product-type', PRODUCT_TYPE);
this.button.setAttribute(PREFIX + 'api-key', API_KEY);
this.button.style.cssText =
`width:100%;height:100%;min-height:44px;border:0;border-radius:4px;font:inherit;cursor:pointer;` +
`background:${BUTTON_COLOR};color:${TEXT_COLOR};`;
this.appendChild(this.button);
}
const product = findProduct();
const button = this.button;
button.setAttribute(PREFIX + 'product-name', product.name || document.title);
button.setAttribute(PREFIX + 'product-image-src', product.image || '');
button.setAttribute(PREFIX + 'product-url', product.url);
if (product.price) button.setAttribute(PREFIX + 'product-price', product.price);
else button.removeAttribute(PREFIX + 'product-price');
}
}
if (!customElements.get('vizbl-try-on')) {
customElements.define('vizbl-try-on', VizblTryOn);
}6. In the settings at the top of the code, paste the two values you copied from the install window:
- replace
full-bodywith the value ofdata-neurodyn-ai-try-on-product-type; - replace
PASTE_WIDGET_KEY_HEREwith the value ofdata-neurodyn-ai-try-on-api-key.
You can also change the button text and colors there.
The product name, image, price, and link — data-neurodyn-ai-try-on-product-name, -product-image-src, -product-price, and -product-url — you don’t fill in. The code takes them from each product page automatically, including the product’s main image that the AI uses for the try-on.
7. Back in the editor, select the element. In Tag Name, enter vizbl-try-on.
8. Publish your site. In the editor, the element may look different or stay empty: Wix shows custom elements in full only on the live site.
Option 2: Custom code
Wix adds custom code only to published sites with a connected domain.
1. In your site’s dashboard, go to Settings. Under Development & integrations, click Custom Code.
2. Click + Add Custom Code and paste this code:
<script>
(() => {
// ===== Settings: change these =====
// Copy both from the same widget's install window in your AI Try-On dashboard
const PRODUCT_TYPE = 'full-body'; // value of data-neurodyn-ai-try-on-product-type
const API_KEY = 'PASTE_WIDGET_KEY_HERE'; // value of data-neurodyn-ai-try-on-api-key
const BUTTON_TEXT = 'Try on';
const BUTTON_COLOR = '#000000';
const TEXT_COLOR = '#ffffff';
const BUTTON_SIDE = 'right'; // 'right' or 'left' corner of the screen
// Product name, image, price, and link are filled in automatically from each product page
// ===== Don't change anything below this line =====
if (window.vizblTryOnLoaded) return;
window.vizblTryOnLoaded = true;
const SCRIPT_SRC = 'https://cdn.neurodyn.ai/@neurodyn/ai-try-on/dist/ai-try-on.embed.min.js';
const PREFIX = 'data-neurodyn-ai-try-on-';
let button = null;
let current = '';
function loadScript() {
if (document.querySelector(`script[src="${SCRIPT_SRC}"]`)) return;
const script = document.createElement('script');
script.src = SCRIPT_SRC;
script.defer = true;
document.head.appendChild(script);
}
function pickImage(image) {
const first = Array.isArray(image) ? image[0] : image;
if (!first) return '';
return typeof first === 'string' ? first : first.contentUrl || first.url || '';
}
function formatPrice(amount, currency) {
if (amount == null || amount === '') return '';
try {
return new Intl.NumberFormat(document.documentElement.lang || undefined, {
style: 'currency',
currency,
}).format(amount);
} catch (e) {
return String(amount);
}
}
function findProduct() {
for (const node of document.querySelectorAll('script[type="application/ld+json"]')) {
let data;
try {
data = JSON.parse(node.textContent);
} catch (e) {
continue;
}
const items = [].concat(data && data['@graph'] ? data['@graph'] : data);
const product = items.find((item) => item && [].concat(item['@type']).includes('Product'));
if (product) {
const offers = product.offers || product.Offers;
const offer = Array.isArray(offers) ? offers[0] : offers || {};
return {
name: product.name || document.title,
image: pickImage(product.image),
price: formatPrice(offer.price != null ? offer.price : offer.lowPrice, offer.priceCurrency),
url: product.url || offer.url || location.href,
};
}
}
return null;
}
function update() {
const product = findProduct();
if (!product) {
if (button) button.style.display = 'none';
return;
}
if (!button) {
button = document.createElement('button');
button.type = 'button';
button.textContent = BUTTON_TEXT;
button.setAttribute(PREFIX + 'dialog', '');
button.setAttribute(PREFIX + 'product-type', PRODUCT_TYPE);
button.setAttribute(PREFIX + 'api-key', API_KEY);
button.style.cssText =
`position:fixed;bottom:20px;${BUTTON_SIDE}:20px;z-index:1000;padding:14px 24px;border:0;` +
`border-radius:999px;background:${BUTTON_COLOR};color:${TEXT_COLOR};font:16px/1 sans-serif;` +
'cursor:pointer;box-shadow:0 4px 16px rgba(0,0,0,.25);';
}
if (!button.isConnected) document.body.appendChild(button);
button.style.display = '';
const key = JSON.stringify(product);
if (key === current) return;
current = key;
button.setAttribute(PREFIX + 'product-name', product.name);
button.setAttribute(PREFIX + 'product-image-src', product.image);
button.setAttribute(PREFIX + 'product-url', product.url);
if (product.price) button.setAttribute(PREFIX + 'product-price', product.price);
else button.removeAttribute(PREFIX + 'product-price');
}
loadScript();
update();
setInterval(update, 700);
})();
</script>3. In the settings at the top of the code, paste the two values you copied from the install window:
- replace
full-bodywith the value ofdata-neurodyn-ai-try-on-product-type; - replace
PASTE_WIDGET_KEY_HEREwith the value ofdata-neurodyn-ai-try-on-api-key.
You can also change the button text, colors, and corner there.
The product name, image, price, and link — data-neurodyn-ai-try-on-product-name, -product-image-src, -product-price, and -product-url — you don’t fill in. The code takes them from each product page automatically, including the product’s main image that the AI uses for the try-on.
4. Name the code, for example Vizbl AI Try-On.
5. Under Add Code to Pages, select All pages and Load code on each new page. The code shows the button only on product pages, but it needs to load everywhere: Wix switches between pages without reloading them.
6. Under Place Code in, select Body - end and click Apply. Custom code runs only on the live site, not in the editor.
Checking that it works
- Open any product page on your live site. The Try on button is where you placed the element, or in the corner of the screen if you used custom code.
- Click Try on. The try-on window opens with your product’s image.
- Open another product and click Try on again. The window shows that product.
If the button is there but the window doesn’t open:
- Check that
PRODUCT_TYPEandAPI_KEYcome from the same widget’s install window. - Check that the domain in your dashboard matches your store’s address.
- Check that your token balance isn’t zero. At zero, try-ons pause and the widget turns off for shoppers.
If the window asks for the wrong photo, like a full-length shot for a T-shirt, the widget type doesn’t match your products. Take PRODUCT_TYPE and API_KEY from the widget of the right type.
The code puts the same button with the same widget type on every product page. If you sell several types of products, or want the button only on some of them, pass this guide to your developer.
Get help in our Discord
Join our Discord to ask questions about these instructions or get technical support. If something isn’t working, open a ticket and our team will investigate.