# WEARFITS Storefront Modal Integration

Last updated: 2026-09-22.

For a storefront and the complete size-fitting experience, prefer the hosted iframe at https://tryon.wearfits.com/?sizeFitting=true. Follow https://tryon.wearfits.com/docs/integration.html for READY/INIT and base product handoff. Put the optional sizeChart sibling field on each WEARFITS_INIT.payload.products[] item; SET_PRODUCTS uses the same product shape. The chart requires version 1, basis "body", unit "cm" or "in", and body ranges for height, chest, waist, hip, or inseam. The storefront exposes no service API key. See https://tryon.wearfits.com/demo_tryon.html.

If the integrator explicitly selects the widget, use the instructions below for its lightweight API-backed modal. It does not include the hosted iframe's size-fitting overlay.

Hosted iframe products use categories top, bottom, fullBody, and shoes; the
lightweight widget below uses top, bottom, full-body, and shoe. Do not share one
category enum blindly between them. With the hosted iframe, wait for
WEARFITS_READY before WEARFITS_INIT, send messages to the explicit
https://tryon.wearfits.com origin, and validate both event.origin and event.source
on incoming messages. The hosted integration guide describes the separate
WEARFITS_SET_PRODUCTS and completion/error events.

## Script

```html
<script src="https://api.wearfits.com/widget/tryon.js" data-storefront-token="wfs1.…"></script>
```

## Open The Modal

```html
<button id="wearfits-tryon">Try on</button>
<script>
  document.getElementById('wearfits-tryon').addEventListener('click', function () {
    Wearfits.openTryOn({
      products: [
        {
          id: 'sku-123',
          name: 'White Cotton Shirt',
          category: 'top',
          images: ['https://shop.example/shirt.jpg'],
          sizes: ['S', 'M', 'L']
        }
      ],
      customer: { gender: 'female', height: 170 }
    });
  });
</script>
```

## Product Categories

For one product the widget sends productImage and productCategory (unknown
categories become auto), including a standalone shoe. For multiple products,
the following slot mapping applies; an outfit must include top, bottom, or
full-body clothing, and shoes are an optional addition:

- `top` maps to `topGarment`
- `bottom` maps to `bottomGarment`
- `full-body` maps to `fullBodyGarment`
- `shoe` maps to `shoes`

## Production Security

For production Shopify and WooCommerce stores, prefer a backend or app proxy that keeps service API keys server-side. The browser widget can point to a proxy by setting `apiBase` in `Wearfits.openTryOn(config)`.

Mint the wfs1. token server-side via POST /api/v1/storefront/tokens with a merchant
key and pass the returned token in data-storefront-token or config.storefrontToken.
It only permits fitting submission and job polling. Renew it after expiry; it
does not authorize the other endpoints. A proxy must implement authentication,
request validation, ownership and rate limits; apiBase only changes the target URL.

## Customer State

The widget saves digitalTwinId in localStorage under wearfits.digitalTwinId.
For custom integrations, associate the ID with the intended customer session
and clear saved state on shared devices or account changes. Check twin validity
and recreate expired avatars. Product sizes and variants are metadata in this
widget; they do not enable size recommendations or the hosted overlay.
