@primestyleai/tryon 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -307
- package/dist/image-utils-usff6Qu8.js +186 -0
- package/dist/{primestyle-tryon.es.js → primestyle-tryon.js} +3 -180
- package/dist/react/index.d.ts +39 -0
- package/dist/react/index.js +771 -0
- package/dist/types.d.ts +55 -0
- package/package.json +25 -8
- package/dist/primestyle-tryon.umd.js +0 -1
package/README.md
CHANGED
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
<h1 align="center">@primestyleai/tryon</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong>AI-Powered Virtual Try-On for
|
|
8
|
+
<strong>AI-Powered Virtual Try-On for React & Next.js</strong>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
|
|
12
|
+
Add a virtual try-on button to your product pages in 3 steps. Customers upload a photo and see how clothes look on them — powered by PrimeStyle AI.
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
16
|
<a href="https://www.npmjs.com/package/@primestyleai/tryon"><img src="https://img.shields.io/npm/v/@primestyleai/tryon?color=D6BA7D&label=npm" alt="npm version" /></a>
|
|
17
17
|
<a href="https://www.npmjs.com/package/@primestyleai/tryon"><img src="https://img.shields.io/npm/dm/@primestyleai/tryon?color=D6BA7D" alt="npm downloads" /></a>
|
|
18
18
|
<a href="https://github.com/primestyleai/tryon-sdk/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@primestyleai/tryon?color=D6BA7D" alt="license" /></a>
|
|
19
|
-
<img src="https://img.shields.io/badge/gzip-
|
|
19
|
+
<img src="https://img.shields.io/badge/gzip-5.5kB-green" alt="bundle size" />
|
|
20
20
|
</p>
|
|
21
21
|
|
|
22
22
|
<p align="center">
|
|
@@ -41,79 +41,24 @@ The entire flow happens inside a beautiful modal — no redirects, no iframes.
|
|
|
41
41
|
|
|
42
42
|
## Quick Start
|
|
43
43
|
|
|
44
|
-
### 1.
|
|
45
|
-
|
|
46
|
-
Sign up at [primestyleai.com](https://primestyleai.com) and create an API key in the [Developer Dashboard](https://primestyleai.com/dashboard/developer/keys).
|
|
47
|
-
|
|
48
|
-
Each try-on costs tokens. New accounts start with free tokens to test. See [Pricing](https://primestyleai.com/pricing) for token packs and plans.
|
|
49
|
-
|
|
50
|
-
### 2. Install
|
|
51
|
-
|
|
52
|
-
**Via npm / yarn / pnpm:**
|
|
44
|
+
### 1. Install
|
|
53
45
|
|
|
54
46
|
```bash
|
|
55
47
|
npm install @primestyleai/tryon
|
|
56
48
|
```
|
|
57
49
|
|
|
58
|
-
|
|
59
|
-
yarn add @primestyleai/tryon
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
pnpm add @primestyleai/tryon
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Via CDN (no build step):**
|
|
67
|
-
|
|
68
|
-
```html
|
|
69
|
-
<script src="https://cdn.primestyleai.com/sdk/primestyle-tryon.js"></script>
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 3. Add to Your Page
|
|
73
|
-
|
|
74
|
-
```html
|
|
75
|
-
<primestyle-tryon
|
|
76
|
-
api-key="ps_live_your_key_here"
|
|
77
|
-
product-image="https://yourstore.com/products/jacket.jpg"
|
|
78
|
-
button-text="Try It On"
|
|
79
|
-
></primestyle-tryon>
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
That's it. The button renders, the modal works, and try-on results stream in real-time.
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Usage
|
|
87
|
-
|
|
88
|
-
### HTML / Script Tag
|
|
89
|
-
|
|
90
|
-
```html
|
|
91
|
-
<!DOCTYPE html>
|
|
92
|
-
<html>
|
|
93
|
-
<head>
|
|
94
|
-
<script src="https://cdn.primestyleai.com/sdk/primestyle-tryon.js"></script>
|
|
95
|
-
</head>
|
|
96
|
-
<body>
|
|
97
|
-
<primestyle-tryon
|
|
98
|
-
api-key="ps_live_your_key_here"
|
|
99
|
-
product-image="https://yourstore.com/products/jacket.jpg"
|
|
100
|
-
></primestyle-tryon>
|
|
101
|
-
</body>
|
|
102
|
-
</html>
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### ES Module Import
|
|
50
|
+
### 2. Set Your API Key
|
|
106
51
|
|
|
107
|
-
|
|
108
|
-
import '@primestyleai/tryon';
|
|
52
|
+
Get your key from the [Developer Dashboard](https://primestyleai.com/dashboard/developer/keys) and add it to your `.env.local`:
|
|
109
53
|
|
|
110
|
-
|
|
54
|
+
```env
|
|
55
|
+
NEXT_PUBLIC_PRIMESTYLE_API_KEY=ps_live_your_key_here
|
|
111
56
|
```
|
|
112
57
|
|
|
113
|
-
###
|
|
58
|
+
### 3. Use the Component
|
|
114
59
|
|
|
115
60
|
```jsx
|
|
116
|
-
import '@primestyleai/tryon';
|
|
61
|
+
import { PrimeStyleTryon } from '@primestyleai/tryon/react';
|
|
117
62
|
|
|
118
63
|
function ProductPage({ product }) {
|
|
119
64
|
return (
|
|
@@ -121,62 +66,38 @@ function ProductPage({ product }) {
|
|
|
121
66
|
<h1>{product.name}</h1>
|
|
122
67
|
<img src={product.image} alt={product.name} />
|
|
123
68
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
product-image={product.image}
|
|
128
|
-
button-text="Try It On"
|
|
69
|
+
<PrimeStyleTryon
|
|
70
|
+
productImage={product.image}
|
|
71
|
+
buttonText="Try It On"
|
|
129
72
|
/>
|
|
130
73
|
</div>
|
|
131
74
|
);
|
|
132
75
|
}
|
|
133
76
|
```
|
|
134
77
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```vue
|
|
138
|
-
<template>
|
|
139
|
-
<div>
|
|
140
|
-
<h1>{{ product.name }}</h1>
|
|
141
|
-
<primestyle-tryon
|
|
142
|
-
:api-key="apiKey"
|
|
143
|
-
:product-image="product.image"
|
|
144
|
-
button-text="Try It On"
|
|
145
|
-
/>
|
|
146
|
-
</div>
|
|
147
|
-
</template>
|
|
148
|
-
|
|
149
|
-
<script setup>
|
|
150
|
-
import '@primestyleai/tryon';
|
|
151
|
-
</script>
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### Shopify / Liquid
|
|
155
|
-
|
|
156
|
-
```html
|
|
157
|
-
<!-- In your product template -->
|
|
158
|
-
<script src="https://cdn.primestyleai.com/sdk/primestyle-tryon.js"></script>
|
|
159
|
-
|
|
160
|
-
<primestyle-tryon
|
|
161
|
-
api-key="ps_live_your_key_here"
|
|
162
|
-
product-image="{{ product.featured_image | img_url: 'master' }}"
|
|
163
|
-
button-text="Try It On"
|
|
164
|
-
></primestyle-tryon>
|
|
165
|
-
```
|
|
78
|
+
That's it. No API key prop needed — the component reads it from your environment automatically.
|
|
166
79
|
|
|
167
80
|
---
|
|
168
81
|
|
|
169
|
-
##
|
|
170
|
-
|
|
171
|
-
|
|
|
172
|
-
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
82
|
+
## Props
|
|
83
|
+
|
|
84
|
+
| Prop | Type | Default | Description |
|
|
85
|
+
|------|------|---------|-------------|
|
|
86
|
+
| `productImage` | `string` | **required** | URL of the garment image |
|
|
87
|
+
| `buttonText` | `string` | `"Virtual Try-On"` | Text on the trigger button |
|
|
88
|
+
| `apiUrl` | `string` | `NEXT_PUBLIC_PRIMESTYLE_API_URL` or production | API endpoint override |
|
|
89
|
+
| `showPoweredBy` | `boolean` | `true` | Show "Powered by PrimeStyle AI" in modal |
|
|
90
|
+
| `buttonStyles` | `ButtonStyles` | `{}` | Customize button via style props |
|
|
91
|
+
| `modalStyles` | `ModalStyles` | `{}` | Customize modal via style props |
|
|
92
|
+
| `classNames` | `PrimeStyleClassNames` | `{}` | Override element classes (Tailwind, CSS) |
|
|
93
|
+
| `className` | `string` | — | Additional CSS class on wrapper |
|
|
94
|
+
| `style` | `CSSProperties` | — | Inline styles on wrapper |
|
|
95
|
+
| `onOpen` | `() => void` | — | Modal opened |
|
|
96
|
+
| `onClose` | `() => void` | — | Modal closed |
|
|
97
|
+
| `onUpload` | `(file: File) => void` | — | User uploaded a photo |
|
|
98
|
+
| `onProcessing` | `(jobId: string) => void` | — | Try-on generation started |
|
|
99
|
+
| `onComplete` | `(result) => void` | — | Result ready: `{ jobId, imageUrl }` |
|
|
100
|
+
| `onError` | `(error) => void` | — | Error occurred: `{ message, code? }` |
|
|
180
101
|
|
|
181
102
|
---
|
|
182
103
|
|
|
@@ -184,28 +105,26 @@ import '@primestyleai/tryon';
|
|
|
184
105
|
|
|
185
106
|
### Button Styles
|
|
186
107
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}'
|
|
205
|
-
></primestyle-tryon>
|
|
108
|
+
```jsx
|
|
109
|
+
<PrimeStyleTryon
|
|
110
|
+
productImage={product.image}
|
|
111
|
+
buttonStyles={{
|
|
112
|
+
backgroundColor: '#000000',
|
|
113
|
+
textColor: '#ffffff',
|
|
114
|
+
borderRadius: '50px',
|
|
115
|
+
padding: '16px 32px',
|
|
116
|
+
fontSize: '16px',
|
|
117
|
+
fontWeight: '700',
|
|
118
|
+
width: '100%',
|
|
119
|
+
border: '2px solid #333',
|
|
120
|
+
hoverBackgroundColor: '#222',
|
|
121
|
+
iconSize: '20px',
|
|
122
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
206
125
|
```
|
|
207
126
|
|
|
208
|
-
**All
|
|
127
|
+
**All ButtonStyles properties:**
|
|
209
128
|
|
|
210
129
|
| Property | Description |
|
|
211
130
|
|----------|-------------|
|
|
@@ -217,7 +136,7 @@ Pass a JSON string to the `button-styles` attribute:
|
|
|
217
136
|
| `fontWeight` | Font weight |
|
|
218
137
|
| `padding` | Inner spacing |
|
|
219
138
|
| `border` | Border style |
|
|
220
|
-
| `width` | Button width (e.g. `"100%"
|
|
139
|
+
| `width` | Button width (e.g. `"100%"`) |
|
|
221
140
|
| `height` | Button height |
|
|
222
141
|
| `hoverBackgroundColor` | Background on hover |
|
|
223
142
|
| `hoverTextColor` | Text color on hover |
|
|
@@ -227,26 +146,25 @@ Pass a JSON string to the `button-styles` attribute:
|
|
|
227
146
|
|
|
228
147
|
### Modal Styles
|
|
229
148
|
|
|
230
|
-
```
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
></primestyle-tryon>
|
|
149
|
+
```jsx
|
|
150
|
+
<PrimeStyleTryon
|
|
151
|
+
productImage={product.image}
|
|
152
|
+
modalStyles={{
|
|
153
|
+
backgroundColor: '#ffffff',
|
|
154
|
+
textColor: '#111111',
|
|
155
|
+
overlayColor: 'rgba(0,0,0,0.7)',
|
|
156
|
+
borderRadius: '16px',
|
|
157
|
+
maxWidth: '520px',
|
|
158
|
+
headerBackgroundColor: '#f5f5f5',
|
|
159
|
+
headerTextColor: '#111111',
|
|
160
|
+
primaryButtonBackgroundColor: '#000000',
|
|
161
|
+
primaryButtonTextColor: '#ffffff',
|
|
162
|
+
loaderColor: '#000000',
|
|
163
|
+
}}
|
|
164
|
+
/>
|
|
247
165
|
```
|
|
248
166
|
|
|
249
|
-
**All
|
|
167
|
+
**All ModalStyles properties:**
|
|
250
168
|
|
|
251
169
|
| Property | Description |
|
|
252
170
|
|----------|-------------|
|
|
@@ -254,8 +172,7 @@ Pass a JSON string to the `button-styles` attribute:
|
|
|
254
172
|
| `backgroundColor` | Modal background |
|
|
255
173
|
| `textColor` | Modal text color |
|
|
256
174
|
| `borderRadius` | Modal corner rounding |
|
|
257
|
-
| `width` | Modal
|
|
258
|
-
| `maxWidth` | Modal max width |
|
|
175
|
+
| `width` / `maxWidth` | Modal dimensions |
|
|
259
176
|
| `fontFamily` | Modal font stack |
|
|
260
177
|
| `headerBackgroundColor` | Header section background |
|
|
261
178
|
| `headerTextColor` | Header title color |
|
|
@@ -270,159 +187,144 @@ Pass a JSON string to the `button-styles` attribute:
|
|
|
270
187
|
| `loaderColor` | Loading spinner color |
|
|
271
188
|
| `resultBorderRadius` | Result image corner rounding |
|
|
272
189
|
|
|
273
|
-
### CSS Custom
|
|
190
|
+
### Tailwind CSS / Custom Classes
|
|
274
191
|
|
|
275
|
-
|
|
192
|
+
Use the `classNames` prop to style any element with Tailwind utilities or your own CSS classes:
|
|
276
193
|
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
194
|
+
```jsx
|
|
195
|
+
<PrimeStyleTryon
|
|
196
|
+
productImage={product.image}
|
|
197
|
+
classNames={{
|
|
198
|
+
button: "bg-black text-white rounded-full px-8 py-4 hover:bg-gray-800",
|
|
199
|
+
modal: "bg-white rounded-2xl shadow-2xl",
|
|
200
|
+
header: "bg-gray-50 border-b border-gray-200",
|
|
201
|
+
title: "text-gray-900 text-lg",
|
|
202
|
+
closeButton: "text-gray-400 hover:text-gray-600",
|
|
203
|
+
body: "p-6",
|
|
204
|
+
uploadZone: "border-2 border-dashed border-gray-300 rounded-xl p-10 hover:border-blue-400",
|
|
205
|
+
uploadText: "text-gray-700",
|
|
206
|
+
submitButton: "bg-blue-600 text-white rounded-lg hover:bg-blue-700",
|
|
207
|
+
downloadButton: "bg-green-600 text-white rounded-lg",
|
|
208
|
+
retryButton: "bg-gray-100 text-gray-700 border border-gray-300",
|
|
209
|
+
}}
|
|
210
|
+
/>
|
|
288
211
|
```
|
|
289
212
|
|
|
290
|
-
|
|
213
|
+
**All classNames keys:**
|
|
214
|
+
|
|
215
|
+
| Key | Element |
|
|
216
|
+
|-----|---------|
|
|
217
|
+
| `root` | Root wrapper `<div>` |
|
|
218
|
+
| `button` | Trigger button |
|
|
219
|
+
| `overlay` | Modal backdrop overlay |
|
|
220
|
+
| `modal` | Modal container |
|
|
221
|
+
| `header` | Modal header bar |
|
|
222
|
+
| `title` | Modal title text |
|
|
223
|
+
| `closeButton` | Close (X) button |
|
|
224
|
+
| `body` | Modal body area |
|
|
225
|
+
| `uploadZone` | Upload drop zone |
|
|
226
|
+
| `uploadText` | "Drop your photo..." text |
|
|
227
|
+
| `uploadHint` | File type hint text |
|
|
228
|
+
| `preview` | Preview image container |
|
|
229
|
+
| `previewImage` | Preview `<img>` element |
|
|
230
|
+
| `removeButton` | Remove preview button |
|
|
231
|
+
| `submitButton` | "Try It On" / "Try Again" button |
|
|
232
|
+
| `spinner` | Loading spinner |
|
|
233
|
+
| `processingText` | "Generating..." text |
|
|
234
|
+
| `processingSubText` | "This usually takes..." text |
|
|
235
|
+
| `result` | Result container |
|
|
236
|
+
| `resultImage` | Result `<img>` element |
|
|
237
|
+
| `resultActions` | Download/retry button row |
|
|
238
|
+
| `downloadButton` | Download button |
|
|
239
|
+
| `retryButton` | "Try Another" button |
|
|
240
|
+
| `error` | Error container |
|
|
241
|
+
| `errorText` | Error message text |
|
|
242
|
+
| `poweredBy` | Footer text |
|
|
243
|
+
|
|
244
|
+
### Normal CSS
|
|
245
|
+
|
|
246
|
+
All elements use `ps-tryon-*` class names that you can target directly in your CSS:
|
|
291
247
|
|
|
292
|
-
```
|
|
293
|
-
|
|
248
|
+
```css
|
|
249
|
+
/* Override the trigger button */
|
|
250
|
+
.ps-tryon-btn {
|
|
251
|
+
background: #000;
|
|
252
|
+
color: #fff;
|
|
253
|
+
border-radius: 50px;
|
|
254
|
+
padding: 16px 32px;
|
|
255
|
+
}
|
|
294
256
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
257
|
+
/* Override the modal */
|
|
258
|
+
.ps-tryon-modal {
|
|
259
|
+
background: #fff;
|
|
260
|
+
color: #111;
|
|
261
|
+
border-radius: 16px;
|
|
262
|
+
}
|
|
301
263
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
264
|
+
/* Override the submit button */
|
|
265
|
+
.ps-tryon-submit {
|
|
266
|
+
background: #2563eb;
|
|
267
|
+
color: #fff;
|
|
268
|
+
}
|
|
307
269
|
```
|
|
308
270
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
## Events
|
|
312
|
-
|
|
313
|
-
Listen for lifecycle events on the component:
|
|
314
|
-
|
|
315
|
-
```javascript
|
|
316
|
-
const tryon = document.querySelector('primestyle-tryon');
|
|
317
|
-
|
|
318
|
-
tryon.addEventListener('ps:open', () => {
|
|
319
|
-
console.log('Modal opened');
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
tryon.addEventListener('ps:upload', (e) => {
|
|
323
|
-
console.log('Photo uploaded:', e.detail.file);
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
tryon.addEventListener('ps:processing', (e) => {
|
|
327
|
-
console.log('Processing job:', e.detail.jobId);
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
tryon.addEventListener('ps:complete', (e) => {
|
|
331
|
-
console.log('Result ready:', e.detail.imageUrl);
|
|
332
|
-
// Track conversion, show upsell, etc.
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
tryon.addEventListener('ps:error', (e) => {
|
|
336
|
-
console.log('Error:', e.detail.message, e.detail.code);
|
|
337
|
-
});
|
|
271
|
+
### Combining Approaches
|
|
338
272
|
|
|
339
|
-
|
|
340
|
-
console.log('Modal closed');
|
|
341
|
-
});
|
|
273
|
+
You can mix all three styling methods — they layer on top of each other:
|
|
342
274
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
275
|
+
```jsx
|
|
276
|
+
<PrimeStyleTryon
|
|
277
|
+
productImage={product.image}
|
|
278
|
+
// 1. Style props (CSS variables)
|
|
279
|
+
buttonStyles={{ width: '100%' }}
|
|
280
|
+
// 2. Tailwind classes
|
|
281
|
+
classNames={{ button: "rounded-full font-bold" }}
|
|
282
|
+
// 3. Normal CSS targets .ps-tryon-btn automatically
|
|
283
|
+
/>
|
|
346
284
|
```
|
|
347
285
|
|
|
348
|
-
|
|
349
|
-
|-------|--------|-------------|
|
|
350
|
-
| `ps:open` | — | Modal opened |
|
|
351
|
-
| `ps:close` | — | Modal closed |
|
|
352
|
-
| `ps:upload` | `{ file: File }` | User uploaded a photo |
|
|
353
|
-
| `ps:processing` | `{ jobId: string }` | Try-on generation started |
|
|
354
|
-
| `ps:complete` | `{ jobId, imageUrl }` | Result image ready |
|
|
355
|
-
| `ps:error` | `{ message, code? }` | Something went wrong |
|
|
356
|
-
| `ps:product-detected` | `{ imageUrl }` | Product image auto-detected from page |
|
|
286
|
+
Priority: Tailwind/classNames classes > CSS variables (buttonStyles/modalStyles) > default styles.
|
|
357
287
|
|
|
358
288
|
---
|
|
359
289
|
|
|
360
|
-
##
|
|
361
|
-
|
|
362
|
-
For advanced use cases, import individual modules:
|
|
363
|
-
|
|
364
|
-
```javascript
|
|
365
|
-
import {
|
|
366
|
-
PrimeStyleTryon, // The Web Component class
|
|
367
|
-
ApiClient, // HTTP client for the VTO API
|
|
368
|
-
SseClient, // SSE real-time updates client
|
|
369
|
-
detectProductImage, // Auto-detect product images on page
|
|
370
|
-
compressImage, // Compress/resize images client-side
|
|
371
|
-
} from '@primestyleai/tryon';
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
### Direct API Usage
|
|
290
|
+
## Callbacks
|
|
375
291
|
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
)
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
// Subscribe to a specific job
|
|
402
|
-
const unsubscribe = sse.onJob(jobId, (update) => {
|
|
403
|
-
if (update.status === 'completed') {
|
|
404
|
-
console.log('Result:', update.imageUrl);
|
|
405
|
-
unsubscribe();
|
|
406
|
-
}
|
|
407
|
-
});
|
|
292
|
+
```jsx
|
|
293
|
+
<PrimeStyleTryon
|
|
294
|
+
productImage={product.image}
|
|
295
|
+
onOpen={() => {
|
|
296
|
+
analytics.track('tryon_opened');
|
|
297
|
+
}}
|
|
298
|
+
onUpload={(file) => {
|
|
299
|
+
console.log('Photo uploaded:', file.name);
|
|
300
|
+
}}
|
|
301
|
+
onProcessing={(jobId) => {
|
|
302
|
+
console.log('Processing:', jobId);
|
|
303
|
+
}}
|
|
304
|
+
onComplete={(result) => {
|
|
305
|
+
console.log('Result ready:', result.imageUrl);
|
|
306
|
+
analytics.track('tryon_completed', { jobId: result.jobId });
|
|
307
|
+
}}
|
|
308
|
+
onError={(error) => {
|
|
309
|
+
console.error('Try-on failed:', error.message);
|
|
310
|
+
// error.code: 'INSUFFICIENT_TOKENS' | 'API_ERROR' | etc.
|
|
311
|
+
}}
|
|
312
|
+
onClose={() => {
|
|
313
|
+
console.log('Modal closed');
|
|
314
|
+
}}
|
|
315
|
+
/>
|
|
408
316
|
```
|
|
409
317
|
|
|
410
318
|
---
|
|
411
319
|
|
|
412
|
-
##
|
|
320
|
+
## Environment Variables
|
|
413
321
|
|
|
414
|
-
|
|
322
|
+
| Variable | Required | Default | Description |
|
|
323
|
+
|----------|----------|---------|-------------|
|
|
324
|
+
| `NEXT_PUBLIC_PRIMESTYLE_API_KEY` | Yes | — | Your PrimeStyle API key |
|
|
325
|
+
| `NEXT_PUBLIC_PRIMESTYLE_API_URL` | No | `https://api.primestyleai.com` | Custom API endpoint |
|
|
415
326
|
|
|
416
|
-
|
|
417
|
-
2. **Schema.org JSON-LD** — `Product.image` in structured data
|
|
418
|
-
3. **Common selectors** — `.product-image img`, `#product-image`, `[data-product-image]`, Shopify/WooCommerce patterns
|
|
419
|
-
|
|
420
|
-
You can also call it programmatically:
|
|
421
|
-
|
|
422
|
-
```javascript
|
|
423
|
-
const tryon = document.querySelector('primestyle-tryon');
|
|
424
|
-
const imageUrl = tryon.detectProduct();
|
|
425
|
-
```
|
|
327
|
+
The component reads these automatically — no need to pass them as props.
|
|
426
328
|
|
|
427
329
|
---
|
|
428
330
|
|
|
@@ -440,11 +342,13 @@ Manage your balance and purchase tokens at [primestyleai.com/dashboard/billing](
|
|
|
440
342
|
|
|
441
343
|
If a try-on fails, tokens are **automatically refunded** to your account.
|
|
442
344
|
|
|
443
|
-
|
|
345
|
+
The `onComplete` callback includes token info:
|
|
444
346
|
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
|
|
347
|
+
```jsx
|
|
348
|
+
onComplete={(result) => {
|
|
349
|
+
// result.jobId — the job ID
|
|
350
|
+
// result.imageUrl — the result image URL
|
|
351
|
+
}}
|
|
448
352
|
```
|
|
449
353
|
|
|
450
354
|
---
|
|
@@ -460,39 +364,63 @@ Create and manage your API keys at the [Developer Dashboard](https://primestylea
|
|
|
460
364
|
|
|
461
365
|
---
|
|
462
366
|
|
|
463
|
-
##
|
|
367
|
+
## Full Example
|
|
464
368
|
|
|
465
|
-
|
|
369
|
+
```jsx
|
|
370
|
+
// app/product/[id]/page.tsx (Next.js App Router)
|
|
466
371
|
|
|
467
|
-
|
|
468
|
-
- Firefox 63+
|
|
469
|
-
- Safari 10.1+
|
|
470
|
-
- Edge 79+
|
|
372
|
+
import { PrimeStyleTryon } from '@primestyleai/tryon/react';
|
|
471
373
|
|
|
472
|
-
|
|
374
|
+
export default function ProductPage({ product }) {
|
|
375
|
+
return (
|
|
376
|
+
<div className="product-page">
|
|
377
|
+
<div className="product-gallery">
|
|
378
|
+
<img src={product.image} alt={product.name} />
|
|
379
|
+
</div>
|
|
380
|
+
|
|
381
|
+
<div className="product-info">
|
|
382
|
+
<h1>{product.name}</h1>
|
|
383
|
+
<p className="price">${product.price}</p>
|
|
384
|
+
|
|
385
|
+
{/* Virtual Try-On — reads API key from env */}
|
|
386
|
+
<PrimeStyleTryon
|
|
387
|
+
productImage={product.image}
|
|
388
|
+
buttonText="Try It On"
|
|
389
|
+
buttonStyles={{
|
|
390
|
+
width: '100%',
|
|
391
|
+
padding: '14px 24px',
|
|
392
|
+
borderRadius: '10px',
|
|
393
|
+
fontSize: '15px',
|
|
394
|
+
}}
|
|
395
|
+
onComplete={(result) => {
|
|
396
|
+
// Show success toast, track analytics, etc.
|
|
397
|
+
toast.success('Your try-on is ready!');
|
|
398
|
+
}}
|
|
399
|
+
onError={(error) => {
|
|
400
|
+
toast.error(error.message);
|
|
401
|
+
}}
|
|
402
|
+
/>
|
|
403
|
+
|
|
404
|
+
<button className="add-to-cart">Add to Cart</button>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
```
|
|
473
410
|
|
|
474
411
|
---
|
|
475
412
|
|
|
476
|
-
##
|
|
413
|
+
## Requirements
|
|
477
414
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
| Vanilla HTML | Full | Just add the script tag |
|
|
481
|
-
| React | Full | Import the package, use JSX |
|
|
482
|
-
| Next.js | Full | Use `'use client'` components |
|
|
483
|
-
| Vue | Full | Import in `<script setup>` |
|
|
484
|
-
| Angular | Full | Add `CUSTOM_ELEMENTS_SCHEMA` |
|
|
485
|
-
| Svelte | Full | Import in `<script>` |
|
|
486
|
-
| Shopify | Full | Add script in theme, use in Liquid |
|
|
487
|
-
| WordPress | Full | Add script in theme header |
|
|
488
|
-
| WooCommerce | Full | Add to product template |
|
|
415
|
+
- React 18+
|
|
416
|
+
- Next.js 13+ (App Router or Pages Router)
|
|
489
417
|
|
|
490
418
|
---
|
|
491
419
|
|
|
492
420
|
## Need Help?
|
|
493
421
|
|
|
494
|
-
- [Documentation](https://primestyleai.com/docs) — Full API reference
|
|
495
422
|
- [Live Demo](https://primestyleai.com/developer/demo) — See it in action
|
|
423
|
+
- [Documentation](https://primestyleai.com/docs) — Full API reference
|
|
496
424
|
- [Dashboard](https://primestyleai.com/dashboard/developer/keys) — Manage keys & tokens
|
|
497
425
|
- [Contact](mailto:support@primestyleai.com) — We're here to help
|
|
498
426
|
|