---
title: "Foot Size Measurement — SDK Guide"
product: size
last_updated: "2026-09-21"
description: "Field reference for the size widget. The rollout order — registration, the millimetre table, and what you must not claim — is Recommend a shoe size."
---


# Foot Size Measurement — SDK Guide

Field reference for the size widget. The rollout order — registration, the millimetre table, and what you must not claim — is [Recommend a shoe size](../shoes/recommend-size.md).

The Size SDK adds a “check my size” action to a shoe product page. It reuses a measurement already stored at [size.wearfits.com](https://size.wearfits.com), or sends the shopper through the iOS App Clip / Android WebXR scan, then shows an advisory recommendation in a modal.

WEARFITS registers your store origins before go-live. Do not put a secret API key in storefront JavaScript.

The widget shows an advisory modal. An on-shoe fit picture is not part of this SDK.

## Before you install

Provide WEARFITS with:

- a stable public `clientId` (for example `example-shop`) — this is not a secret
- every production and staging **origin** (`scheme://host[:port]`) that will host the widget
- languages you need (`pl`, `en`, `fr`, `es` are included)

Register `https://shop.example.com` and `https://staging-shop.example.com` separately. Production origins must use HTTPS.

Use a stable `productId` for the same product/variant. Do not mint a new id on every fit request.

Public demo: [size.wearfits.com/demo_size.html](https://size.wearfits.com/demo_size.html)

## What the store receives

The store sends internal shoe dimensions. The fit API returns a **derived** recommendation — not raw foot dimensions, not a scan id:

```json
{
  "recommendation": {
    "size": "43",
    "confidence": "advisory",
    "fit": {
      "overall": "good",
      "length": "good",
      "width": "good",
      "instep": "tight"
    }
  },
  "alternatives": [],
  "algorithmVersion": "1"
}
```

`confidence` is always `"advisory"`. Do not block checkout or describe this as a guaranteed fit.

## Shoe-size table

Pass `tryonSizeFit` without renaming fields:

```js
const tryonSizeFit = {
  unit: "mm",
  sizes: [
    { name: "41", length: 265, width: 98, instep: 240 },
    { name: "42", length: 272, width: 100, instep: 244 },
    { name: "43", length: 279, width: 102, instep: 248 }
  ]
};
```

- `unit` must be `"mm"`
- `sizes` has 1–64 rows
- `name` is the customer-facing label (EU, `US 9`, and similar are allowed)
- `length` (mm) is required; `width` and `instep` are optional millimetre values

## Content Security Policy

Allow:

```text
script-src https://size.wearfits.com
style-src https://size.wearfits.com
connect-src https://size.wearfits.com
navigate-to https://size.wearfits.com
```

Merge these into the existing policy. The SDK uses a popup or redirect, not an iframe, so `frame-src 'none'` is compatible.

## Install: SDK button

```html
<div id="wearfits-size"></div>
<script type="module">
  import { mount } from "https://size.wearfits.com/sdk/v1/index.js";

  const wearfitsSize = mount("#wearfits-size", {
    clientId: "example-shop",
    productId: "SKU-123",
    lang: "en",
    tryonSizeFit: {
      unit: "mm",
      sizes: [
        { name: "41", length: 265, width: 98, instep: 240 },
        { name: "42", length: 272, width: 100, instep: 244 },
        { name: "43", length: 279, width: 102, instep: 248 }
      ]
    }
  });
</script>
```

`mount()` creates the button and an accessible result modal (Shadow DOM).

## Install: your own button

```html
<button id="check-shoe-size" type="button">Check my size</button>
<script type="module">
  import { attach } from "https://size.wearfits.com/sdk/v1/index.js";

  const wearfitsSize = attach("#check-shoe-size", {
    clientId: "example-shop",
    productId: "SKU-123",
    lang: "en",
    tryonSizeFit
  });
</script>
```

## Product changes (SPA)

```js
wearfitsSize.updateProduct({
  productId: nextProduct.sku,
  tryonSizeFit: nextProduct.tryonSizeFit
});
```

That clears the displayed recommendation but keeps the shopper credential so a second shoe can be checked without a new scan. Call `wearfitsSize.destroy()` when removing the product page.

`open()`, `updateProduct()`, and `destroy()` are the public instance methods.

Events (no foot data): `wearfits:size:open`, `wearfits:size:handoff`, `wearfits:size:recommendation`, `wearfits:size:error`.

## Shopper flow

1. Shopper activates the size button.
2. If the store already has a valid credential, the SDK requests a recommendation immediately.
3. Otherwise the shopper goes to `size.wearfits.com`. An existing profile returns at once; otherwise they scan (iOS App Clip or Android WebXR).
4. The SDK sends the credential plus `tryonSizeFit` and shows the result modal.

Popup/new-tab is preferred; a same-tab redirect is the fallback if the popup is blocked.

## Troubleshooting

| Symptom | What to check |
|---------|----------------|
| `merchant_not_allowed` / `origin_not_allowed` | Exact `clientId` and full origin (www vs apex, http vs https, port) |
| Module blocked | CSP `script-src`, `style-src`, `connect-src` include `https://size.wearfits.com` |
| No modal after return | Return page is the same origin, SDK mounted with the same `clientId` |
| `popup_closed` | Shopper closed the popup; they can tap the button again |

## Next

- [Overview](overview.md)
- [User guide](user-guide.md)
