Get started
Website widget
Paste two lines of HTML and your product pages get the same Try it on button and panel as our Shopify app. Works on any site: custom-built, Wix, Squarespace, Webflow, React, Next.js or plain HTML. No server, no API calls to write.
Set it up
- Sign in at app.clothsyai.fabricvton.com and open Website widget. New accounts start with 20 free credits.
- Enter your website domains, e.g.
yourstore.com, and click Create widget key. Subdomains are included. If your product images live on another host (a CDN), add that host too. - Copy the two snippets from that page into your site, as below.
1. The script, once per page
<!-- Once per page, just before </body> -->
<script src="https://api.clothsyai.fabricvton.com/widget/v1.js"
data-key="clothsy_pub_..." defer></script>2. The button, on each product page
<!-- Where the button should appear, on each product page -->
<div data-clothsy-tryon
data-product-image="https://yourstore.com/images/denim-jacket.jpg"
data-product-title="Denim jacket"></div>That's all. The button appears where you put the element, and opening it shows the panel: the shopper uploads a photo or takes one in a mirror, agrees to how it's used the first time, and sees the result with a before/after slider. Their past try-ons stay in the panel's history for the visit.
Button options
| Attribute | What it does |
|---|---|
data-product-image | Required. The product photo to try on: a public HTTPS JPEG or PNG on one of your allowed domains. A relative path like /images/jacket.jpg also works. |
data-product-title | The product's name. Shown in the panel and improves results. |
data-add-to-cart | A CSS selector for your page's own Add to cart button, e.g. #add-to-cart. The result then shows Add to Cart, which clicks your button, so your variants, stock checks and cart drawer behave as usual. |
data-button-text | The button's label. Default: Try it on. |
data-button-color | Button background, e.g. #101014 (default) or rgb(16,16,20). |
data-text-color | Button text colour. Default: #ffffff. |
data-radius | Corner radius, e.g. 12px (default) or 999px for a pill. |
data-full-width | false makes the button only as wide as its label. Default: full width. |
<div data-clothsy-tryon
data-product-image="https://yourstore.com/images/denim-jacket.jpg"
data-product-title="Denim jacket"
data-add-to-cart="#add-to-cart"
data-button-text="See it on me"
data-button-color="#6c4fe0"
data-text-color="#ffffff"
data-radius="999px"
data-full-width="false"></div>Use your own button
Put your own markup inside the element and the widget leaves it as it is; clicking it opens the panel.
<div data-clothsy-tryon data-product-image="https://yourstore.com/images/denim-jacket.jpg">
<button class="my-button">Try it on</button>
</div>React, Next.js and other frameworks
Load the script once in your layout, then render the element wherever you like. Buttons added later, for example after client-side navigation, are picked up automatically. For full control from your own server, use the Next.js helper or the SDK instead.
// Any framework: render the element; the script finds it, also after client-side navigation.
export function TryOnButton({ product }) {
return (
<div
data-clothsy-tryon
data-product-image={product.imageUrl}
data-product-title={product.name}
data-add-to-cart="#add-to-cart"
/>
);
}Why the key can be public
The widget key (clothsy_pub_…) sits in your page source, so anyone can read it. It is built for that, and it is not your secret API key:
- Your domains only. It works only on pages served from the domains you listed. Requests from any other site are refused.
- Your product images only. The image being tried on must come from those domains, so nobody can use your credits on other pictures.
- Limits per shopper. Each visitor can start only a few try-ons an hour, and you can set a daily limit for the whole site.
- Start and check only. It can start a try-on and read that try-on's result, nothing else: no account data, no other try-ons, no settings.
- Replace it any time. Replace key in the platform turns the old one off at once.
Credits
Each finished try-on uses one credit from your account, the same balance as your API keys. A try-on that fails is refunded. See today's count next to your snippet in the platform.
Privacy
The shopper's photo is resized in their browser and sent with the try-on; it is never stored. Before the first try-on the panel asks the shopper to confirm they are 18 or older and that it's their photo, and links to the shopper privacy notice. Mention virtual try-on in your own privacy policy too.
Troubleshooting
| The panel says | Fix |
|---|---|
| “Virtual try-on isn't enabled for this website yet.” | The page's domain isn't in your allowed list. Add it under Website widget in the platform (subdomains are included). |
| “This product's image isn't on an allowed domain.” | data-product-image points at a host not in your list, often an image CDN. Add that host too. |
| “This try-on button isn't set up correctly.” | The data-key is missing or wrong, or the key was replaced. Copy the snippet again from the platform. |
| “This try-on button is missing its product image.” | Add data-product-image to the element. |
| “Virtual try-on isn't available on this website right now.” | The account is out of credits. Add credits in the platform. |
| “…reached today's limit on this website.” | Your optional daily limit was reached. Raise or remove it in the platform. |
Testing on your computer? Add localhost to your domains. On a live site the page must use HTTPS.

