> For the complete documentation index, see [llms.txt](https://docs.akinon.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.akinon.com/technical-guides/virtual-try-on-vto/installation-and-integration.md).

# Installation & Integration

Virtual Try On is an AI-based project that allows the customer to try on the relevant product on a photo they have uploaded. The flow is completed through 3 core applications:

* **Virtual Try On Extension**
* **Frontend (Next or Python)**
* **Mobile App**

***

## <mark style="color:red;">1. Installation</mark>

#### Extension

| Variable                            | Value / Description                                                                                  |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `DB_SSL`                            | `true`                                                                                               |
| `DB_SCHEMA`                         | `.public`                                                                                            |
| `APP_TEST_MODE`                     | `false`                                                                                              |
| `APP_SERVER_PORT`                   | `:8008`                                                                                              |
| `SEC_API_AUTH_PASSWORD`             | 20-character combination of uppercase, lowercase letters and numbers *(must be entered as a secret)* |
| `API_AUTH_USERNAME`                 | 15-character combination of uppercase, lowercase letters and numbers                                 |
| `PROCESS_MONITORING`                | `false`                                                                                              |
| `GOOGLE_OAUTH_ADDRESS`              | `https://oauth2.googleapis.com/token`                                                                |
| `APP_LIMITED_CATEGORIES`            | Comma-separated FE category IDs for categories where try-on should be disabled                       |
| `APP_SERVER_ACCESS_LOGS`            | `true`                                                                                               |
| `VERTEX_AI_IMAGE_FORMAT`            | `base64`                                                                                             |
| `INF_TRY_ON_RATE_LIMITER`           | `250-M`                                                                                              |
| `API_ALLOWED_IMAGE_DOMAINS`         | Root domain names of the CDNs where product images are hosted (e.g. `akinoncloud.com`)               |
| `DB_CONNECTION_POOL_MAX_SIZE`       | `20`                                                                                                 |
| `DB_CONNECTION_POOL_MIN_SIZE`       | `10`                                                                                                 |
| `TOGGLE_IMAGE_GENERATION_ENABLED`   | `true`                                                                                               |
| `S3_PRESIGN_EXPIRE_MINUTES`         | `30`                                                                                                 |
| `S3_PRESIGN_LISTING_EXPIRE_MINUTES` | `300`                                                                                                |

#### FE-Next

*(To be filled)*

#### FE-Python

*(To be filled)*

## <mark style="color:red;">Mobile App</mark>

{% hint style="info" %}
This feature is available for projects using `env6.1.0` **or higher**.
{% endhint %}

Two entry points are provided by the framework:

* **Product Detail Page**: single-product try-on via the `VirtualTry` button.
* **Basket Page**: multi-product try-on ("Virtual Cabin") via `MultipleVirtualTryButton`, letting the user select up to 3 products from their basket to try on together.

Before any photo is uploaded, the user must accept an explicit consent text (`CONTRACT_TEXT`) covering AI-based processing of their photo. This text is brand-owned copy, not framework boilerplate — each brand must review and localize it before release, since it is a legal/consent statement, not a UI label.

### <mark style="color:red;">**Platform Setup**</mark>

**Android Configuration**

Add the required permission to the `akinon.json` file for Android:

```json
{
  "android": {
    "permissions": [
      "android.permission.CAMERA"
    ]
  }
}
```

**iOS Configuration**

Add the required permissions to the `akinon.json` file for iOS:

```json
{
  "ios": {
    "infoPlist": {
      "NSCameraUsageDescription": "This app requires camera access to take photos for virtual try-on.",
      "NSPhotoLibraryUsageDescription": "This app requires photo library access to select photos for virtual try-on."
    }
  }
}
```

By default, a new project's `akinon.json` has `android.permissions: []` and no `ios.infoPlist` key at all — both must be added explicitly.

### <mark style="color:red;">**Project Setup**</mark>

Projects created on `env6.1.0` or later already include these files and config; verify each item below rather than adding it from scratch. Projects upgraded from an earlier env need to add what's missing.

#### <mark style="color:red;">**1. Default Styles, Text and Theme Config**</mark>

Add and register the following files (the full file diff for the env6.1.0 upgrade, where this feature was introduced, is available at [abp.akinon.net/upgrade-helper](https://abp.akinon.net/upgrade-helper)):

* `src/staticTextMaps/virtualTryOn.json`: all VTO copy (button labels, consent text, feedback, tooltips, tips for a good photo, etc.)
* `src/styles/virtualTryOn/gridElements.js` and `src/styles/virtualTryOn/index.js`: VTO styles
* `src/themeConfigs/virtualTryOn.js`: grid sizing for product selection / product list / product detail image containers

Register the new style and theme modules in the project's aggregators:

```js
// src/styles/index.js
import * as virtualTryOn from './virtualTryOn';

export default {
  // ...existing styles
  virtualTryOn,
};
```

```js
// src/themeConfigs/index.js
import virtualTryOn from './virtualTryOn';

export default {
  // ...existing theme configs
  virtualTryOn,
};
```

Permission and cropper texts — the permission-denied alerts and native cropper shown by VTO's camera/gallery picker (see `useVirtualTry.js`) read the following keys. Define them directly in `src/staticTextMaps/virtualTryOn.json`:

* `NO_CAMERA_PERMISSION_TITTLE` / `NO_CAMERA_PERMISSION_MESSAGE`
* `NO_GALLERY_PERMISSION_TITTLE` / `NO_GALLERY_PERMISSION_MESSAGE`
* `CANCEL`, `SETTINGS`
* `CROPPER_TOOLBAR_TITLE`, `IOS_CROPPER_CANCEL_TEXT`, `IOS_CROPPER_CHOOSE_TEXT`

#### <mark style="color:red;">**2. Icon Configuration**</mark>

VTO's components reference the following Icomoon icon names — add any that are missing from the project's icon font:

* `camera`
* `gallery`
* `check`
* `thumbs-up`
* `thumbs-down`
* `virtual-try`
* `retry`

#### <mark style="color:red;">**3. API Endpoint Configuration**</mark>

Add the Virtual Try On Extension endpoints to `src/integrationMaps/urls.json`:

```json
{
  "VIRTUAL_TRY_ON": "https://<your-vto-extension-host>/api/v1/virtual-try-on",
  "VIRTUAL_TRY_ON_ASYNC": "https://<your-vto-extension-host>/api/async/v1/virtual-try-on",
  "VIRTUAL_TRY_ON_STATUS": "https://<your-vto-extension-host>/api/async/v1/job-status",
  "MULTIPLE_VIRTUAL_TRY_ON": "https://<your-vto-extension-host>/api/v1/multiple-virtual-try-on",
  "ASYNC_MULTIPLE_VIRTUAL_TRY_ON": "https://<your-vto-extension-host>/api/async/v1/multiple-virtual-try-on",
  "VIRTUAL_TRY_ON_FEEDBACK": "https://<your-vto-extension-host>/api/v1/feedback",
  "VIRTUAL_TRY_ON_LIMITED_CATEGORIES": "https://<your-vto-extension-host>/api/v1/limited-categories",
  "VIRTUAL_TRY_WIDGET": "mobile-virtual-try-status"
}
```

`VIRTUAL_TRY_WIDGET` is an Omnitron widget key, not a URL — keep its value as-is (see Visibility Control below).

Replace `<your-vto-extension-host>` with the brand's own Virtual Try On Extension deployment; do not ship the shared/demo host used during development.

The flow also relies on two endpoints that don't share the `VIRTUAL_TRY*` prefix and are easy to miss:

```json
{
  "GENERATE_BREADCRUMB": "menus/generate_breadcrumb/",
  "PRODUCT_CATEGORY_NODES": "products/$productPk/category_nodes/?limit=1&format=json"
}
```

#### <mark style="color:red;">**4. Basket Extra Data Configuration**</mark>

The multi-product flow needs each basket product's image data. Add `productimage_set` to the `PRODUCT` config's `EXTRA_DATA` in `src/integrationMaps/basket.json`:

```diff
 "PRODUCT": {
   "BRAND": "",
   "ATTRIBUTES": [],
   "VARIANTS": [],
-  "EXTRA_DATA": []
+  "EXTRA_DATA": [
+    {
+      "key": "productimage_set",
+      "selector": "product.productimage_set"
+    }
+  ]
 }
```

If `productMapper` is overridden in `src/dataContainers/basket/model/index.js`, add the same `EXTRA_DATA` entry there as well.

#### <mark style="color:red;">**Visibility Control**</mark>

VTO buttons can be toggled via an Omnitron widget, keyed `mobile-virtual-try-status` (the `VIRTUAL_TRY_WIDGET` value above). If the widget is not configured in Omnitron, the buttons are visible by default — this is the mechanism for staged/observation-mode rollout on mobile.

Create the widget in Omnitron with this schema:

```json
{
  "show": {
    "key": "show",
    "label": "Virtual Try Visibility",
    "choices": [
      { "label": "Active", "value": "true" },
      { "label": "Inactive", "value": "false" }
    ],
    "required": true,
    "data_type": "dropdown",
    "is_localizable": false
  }
}
```

A single `show` field, dropdown type, with "Active" (true) / "Inactive" (false) choices. Setting it to "Inactive" hides the buttons; "Active" (or leaving the widget unconfigured) keeps them visible.

### <mark style="color:red;">**Implementation Guide**</mark>

**Product Detail Page Implementation**

In `src/pages/productDetail/index.js`, import and use the `VirtualTry` (single try-on) component:

```jsx
import VirtualTry from "_components/virtualTry/singleVirtualTryButton";

const ProductDetailGrid = (pageContext) => {
  const { product } = pageContext;

  return (
    <VirtualTry
      product={product}
    />
  );
};
```

**Props:**

| Prop                   | Type          | Required | Description                                                 |
| ---------------------- | ------------- | -------- | ----------------------------------------------------------- |
| `product`              | Object        | Yes      | The current product; used to launch the single try-on flow. |
| `content`              | Function/Node | No       | Overrides the default button content.                       |
| `onPress`              | Function      | No       | Overrides the default press handler.                        |
| `checkboxModalContent` | Function/Node | No       | Overrides the consent checkbox modal content.               |
| `checkboxContent`      | Function/Node | No       | Overrides the consent checkbox content.                     |
| `bottomSheetContent`   | Function/Node | No       | Overrides the consent bottom sheet content.                 |

**Basket Page Implementation**

In `src/pages/basket/index.js`, import and use the `MultipleVirtualTryButton` component:

```jsx
import MultipleVirtualTryButton from '_components/virtualTry/multipleVirtualTryButton';

const BasketGrid = (pageContext) => {
  const {
    basket: { products = [] } = {},
  } = pageContext;

  return (
    <MultipleVirtualTryButton
      products={products}
    />
  );
};
```

`products` is the basket's product list, taken from the basket data container's state (not a plain page prop).

Props:

| Prop                   | Type          | Required | Description                                                    |
| ---------------------- | ------------- | -------- | -------------------------------------------------------------- |
| `products`             | Array         | Yes      | Basket products eligible for try-on; the user selects up to 3. |
| `bottomSheetContent`   | Function/Node | No       | Overrides the consent bottom sheet content.                    |
| `checkboxContent`      | Function/Node | No       | Overrides the consent checkbox content.                        |
| `checkboxModalContent` | Function/Node | No       | Overrides the consent checkbox modal content.                  |

***

## <mark style="color:red;">2. Observation Mode Controls</mark>

Before the application is fully released to end customers, controls must be performed in observation mode. In a deployment made in this mode, end customers cannot directly see the new features. However, the features become accessible when `enable_virtual_try_on=true` is added to the browser's local storage.

Comprehensive controls must be performed including:

* Query speed for both direct queries using the product's existing image and queries made with cropping
* Similar product checks
* Error checks

{% hint style="danger" %}
The product must **NEVER** be released directly to the end customer without these controls being completed.
{% endhint %}

***

## <mark style="color:red;">3. Release to End Customer</mark>

Once the controls are completed, the FE applications must make the feature available to end customers either by deploying a new release or by making a parameter change.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.akinon.com/technical-guides/virtual-try-on-vto/installation-and-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
