Skip to main content

AI Virtual Try-On

The cv-tryon addon lets customers see their customized product on AI-generated model photos. It uses FASHN.ai under the hood to dress a model with the current canvas design, and optionally generate short videos from the results.

How It Works

  1. The user opens the try-on drawer (via action button or programmatically).
  2. They select a product view and optionally pick a model photo.
  3. The component captures the canvas as a PNG and sends it to your server-side proxy endpoint.
  4. Your server forwards the request to FASHN.ai, polls for completion, and returns the result images.
  5. The user can enlarge results in a lightbox, download them, or generate a short video.

Quick Start

Place the <cv-tryon> element anywhere on the page. Configure models and endpoints via ChamevoOptions.tryOn:

<cv-customizer id="customizer"></cv-customizer>
<cv-tryon id="tryon"></cv-tryon>

<script type="module">
import { createCustomizer } from '@chamevo/customizer';

const customizer = createCustomizer('#customizer', {
tryOn: {
endpoint: '/api/fashn/product-to-model',
videoEndpoint: '/api/fashn/image-to-video',
models: [
{
id: 'female-1',
label: 'Sofia',
subtitle: 'Slim, casual',
thumb: '/images/models/sofia-thumb.jpg',
full: '/images/models/sofia-full.jpg',
},
{
id: 'male-1',
label: 'Marcus',
subtitle: 'Athletic, smart',
thumb: '/images/models/marcus-thumb.jpg',
full: '/images/models/marcus-full.jpg',
},
],
allowUpload: true,
},
});

customizer.addEventListener('cvReady', (e) => {
document.getElementById('tryon').chamevo = e.detail.chamevo;
});
</script>

If no models are configured, only the upload card and the "Skip" option are available.

Adding the Action Button

Use the built-in ai-try-on action ID to add a trigger button to the action bar. It renders as an animated gradient widget button:

customizer.options = {
actions: [
{ items: ['undo', 'redo'], align: 'start' },
{ items: ['ai-try-on'], align: 'end' },
],
};

The ai-try-on action is a widget action — it renders the <cv-tryon-button> component inline and never collapses into a dropdown.

You can also use <cv-tryon-button> as a standalone element anywhere on your page:

<cv-tryon-button label="Try It On"></cv-tryon-button>

cv-tryon-button Properties

PropertyTypeDefaultDescription
labelstring'AI Try On'Button label text.
size'sm' | 'md''md'Size variant. 'sm' is used automatically in the actions bar.

Server-Side Proxy

The component does not call FASHN.ai directly from the browser. You must provide two server endpoints that proxy requests to the FASHN.ai API:

  1. Receive the request from the component.
  2. Forward it to FASHN with your API key (submit job → poll status).
  3. Download the output files to your server.
  4. Return local URLs to the client.

This keeps your FASHN API key secure and avoids CORS issues.

POST /api/fashn/product-to-model

Try-on image generation. The component sends this request when the user clicks Generate Try-On.

Request Body

{
"product_image": "data:image/png;base64,iVBORw0KGgo…",
"model_image": "https://example.com/model-photo.jpg",
"prompt": "studio lighting, white background"
}
FieldTypeRequiredDescription
product_imagestringYesBase64 data URI of the canvas view (PNG).
model_imagestringNoURL or base64 of the model photo. If omitted, FASHN generates a model automatically.
promptstringNoStyle prompt for the generation (e.g. "outdoor photoshoot").

Your server may also forward these optional FASHN parameters if provided:

FieldTypeDescription
image_promptstringImage-based style prompt.
face_referencestringURL or base64 of a face reference image.
face_reference_mode'match_reference' | 'match_base'How to use the face reference.
aspect_ratiostringOutput aspect ratio (e.g. "3:4").
resolution'1k' | '4k'Output resolution.
background_referencestringURL or base64 of a background reference.
seednumberRandom seed for reproducibility.
num_imagesnumberNumber of images to generate (default 1).
output_format'png' | 'jpeg'Output image format.

200 Response

{
"images": [
"/uploads/2026/02/fashn_1740700000_0.png",
"/uploads/2026/02/fashn_1740700000_1.png"
]
}
FieldTypeDescription
imagesstring[]Array of public URL paths to the generated images on your server. Must be accessible by the browser.

The component renders each URL as a result card with enlarge, download, and video-generation actions.

Error Response

On failure, return a non-200 status code. The component reads the response body as text and displays it as an error message:

HTTP 500
{"error": "FASHN job failed: Invalid product image"}

POST /api/fashn/image-to-video

Video generation from a try-on result image. The component sends this request when the user clicks the play icon on a result card.

Request Body

{
"image": "/uploads/2026/02/fashn_1740700000_0.png",
"resolution": "720p",
"duration": 5
}
FieldTypeRequiredDescription
imagestringYesURL path of the source image (from the try-on images response). Can be a local path — your server must resolve it to a file or convert to base64 before forwarding to FASHN.
resolutionstringYesVideo resolution. The component sends "720p".
durationnumberYesVideo duration in seconds. The component sends 5.
promptstringNoMotion/style prompt for the video.

Your server should detect local paths (e.g. /uploads/…), read the file from disk, and convert it to a base64 data URI before sending to FASHN — the FASHN API does not accept local paths.

200 Response

{
"videos": [
"/uploads/2026/02/fashn_video_1740700100_0.mp4"
]
}
FieldTypeDescription
videosstring[]Array of public URL paths to the generated .mp4 video files on your server.

The component renders each video with inline playback controls, a download link, and an enlarge button (opens in the lightbox).

Error Response

Same pattern as the try-on endpoint — return a non-200 status with an error message in the body.

Configuration (ChamevoOptions.tryOn)

The try-on feature is configured via the tryOn property in ChamevoOptions. This is the recommended way to set models, endpoints, and behavior:

interface TryOnConfig {
/** API endpoint for try-on image generation. @default '/api/fashn/product-to-model' */
endpoint?: string;
/** API endpoint for image-to-video generation. @default '/api/fashn/image-to-video' */
videoEndpoint?: string;
/** Model images available for selection. @default [] */
models?: TryOnModel[];
/** Allow users to upload their own photo as model. @default true */
allowUpload?: boolean;
}

Model Data Format (TryOnModel)

interface TryOnModel {
id: string; // Unique identifier
label: string; // Display name shown below the thumbnail
subtitle?: string; // Secondary text (e.g. "Slim, casual")
thumb: string; // Thumbnail URL (~300×400 recommended)
full: string; // Full-resolution URL sent to the API (~800×1067)
}

When no models are configured, only the upload card and the "Skip" option are shown. The user can skip model selection entirely — the FASHN API will generate its own model automatically (costs 1 credit instead of 2).

Example

createCustomizer('#customizer', {
tryOn: {
models: [
{ id: 'f1', label: 'Sofia', subtitle: 'Slim, casual', thumb: '/models/sofia-sm.jpg', full: '/models/sofia.jpg' },
{ id: 'm1', label: 'Marcus', subtitle: 'Athletic', thumb: '/models/marcus-sm.jpg', full: '/models/marcus.jpg' },
],
allowUpload: false, // disable user photo uploads
},
});

Runtime Updates

You can update the try-on config at runtime via setOptions:

chamevo.setOptions({
tryOn: {
models: [...newModels],
},
});

Component Reference (cv-tryon)

Properties

PropertyTypeDefaultDescription
chamevoChamevoJSAuto from storeChamevoJS instance. Falls back to the internal store if not set.
openbooleanfalseControls drawer visibility.
endpointstringFrom options.tryOnServer endpoint for try-on generation. Overrides the options value.
videoEndpointstringFrom options.tryOnServer endpoint for video generation. Overrides the options value.
modelsstring | TryOnModel[]From options.tryOnPredefined model images. Overrides the options value. Pass a JSON string or array.

Direct props on the <cv-tryon> element override options.tryOn values. The resolution order is: prop > options.tryOn > default.

Events

Evente.detailDescription
cvTryOnOpenFires when the drawer opens.
cvTryOnCloseFires when the drawer closes.
cvTryOnGenerate{ images: string[] }Fires when generation completes with result image URLs.

Opening Programmatically

Toggle the drawer from JavaScript:

// Via the component's open prop
document.querySelector('cv-tryon').open = true;

// Or via the action system
document.querySelector('cv-customizer')
.dispatchEvent(new CustomEvent('cv-action-request', {
detail: { action: 'ai-try-on' },
}));

Features

Stepped Wizard

The try-on flow is a 4-step wizard: Design → Model → Style → Result. Users can navigate back to previous steps by clicking the stepper dots.

Skip Model Selection

Users can skip the model step by clicking "Skip — let AI choose the model". When skipped, no model_image is sent to the FASHN API, which generates its own model based on the garment image. This is useful for back/side views where the model orientation matters.

Image Lightbox

Click the enlarge icon on any result image to open it in a fullscreen lightbox overlay. Press Escape or click the background to close.

Image-to-Video

Click the video icon on a result image to generate a short video (720p, 5 seconds) using FASHN's image-to-video API. The video appears below the image results with playback controls and download/enlarge options.

Result History

Generated images and videos are stored in the browser's localStorage (up to 10 most recent entries). A horizontal "Recent" strip appears between the stepper and the wizard body, showing thumbnails of past results. Click a thumbnail to open it in the lightbox. Hover to reveal the delete button.

History persists across drawer open/close and page refreshes.

Session Persistence

Closing and reopening the drawer preserves the current generation state — results, loading spinners, and video output remain visible without needing to refresh the page.

i18n

The action button label is translatable via the actions.ai_try_on key:

customizer.options = {
langJSON: {
actions: {
ai_try_on: 'Virtuelles Anprobieren',
},
},
};

See i18n for full translation setup.

Next Steps