@primestyleai/tryon 1.0.1 → 1.1.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 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 Any E-Commerce Site</strong>
8
+ <strong>AI-Powered Virtual Try-On for React & Next.js</strong>
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- Drop a single Web Component into your product page and let customers see how clothes look on them — powered by PrimeStyle AI.
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-7kB-green" alt="bundle size" />
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. Get Your API Key
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
- ```bash
59
- yarn add @primestyleai/tryon
60
- ```
61
-
62
- ```bash
63
- pnpm add @primestyleai/tryon
64
- ```
65
-
66
- **Via CDN (no build step):**
50
+ ### 2. Set Your API Key
67
51
 
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.
52
+ Get your key from the [Developer Dashboard](https://primestyleai.com/dashboard/developer/keys) and add it to your `.env.local`:
83
53
 
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>
54
+ ```env
55
+ NEXT_PUBLIC_PRIMESTYLE_API_KEY=ps_live_your_key_here
103
56
  ```
104
57
 
105
- ### ES Module Import
106
-
107
- ```javascript
108
- import '@primestyleai/tryon';
109
-
110
- // The <primestyle-tryon> custom element is now registered globally
111
- ```
112
-
113
- ### React
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,37 @@ function ProductPage({ product }) {
121
66
  <h1>{product.name}</h1>
122
67
  <img src={product.image} alt={product.name} />
123
68
 
124
- {/* @ts-expect-error Web Component */}
125
- <primestyle-tryon
126
- api-key="ps_live_your_key_here"
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
- ### Vue
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
- ## Attributes
170
-
171
- | Attribute | Type | Default | Description |
172
- |-----------|------|---------|-------------|
173
- | `api-key` | `string` | **required** | Your PrimeStyle API key (starts with `ps_live_`) |
174
- | `product-image` | `string` | auto-detected | URL of the garment image. If omitted, the SDK auto-detects from the page |
175
- | `api-url` | `string` | `https://api.primestyleai.com` | API endpoint (only change for self-hosted) |
176
- | `button-text` | `string` | `"Virtual Try-On"` | Text displayed on the button |
177
- | `show-powered-by` | `string` | `"true"` | Show "Powered by PrimeStyle AI" in the modal footer |
178
- | `button-styles` | `JSON string` | `{}` | Customize button appearance (see below) |
179
- | `modal-styles` | `JSON string` | `{}` | Customize modal appearance (see below) |
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 appearance |
91
+ | `modalStyles` | `ModalStyles` | `{}` | Customize modal appearance |
92
+ | `className` | `string` | | Additional CSS class on wrapper |
93
+ | `style` | `CSSProperties` | — | Inline styles on wrapper |
94
+ | `onOpen` | `() => void` | — | Modal opened |
95
+ | `onClose` | `() => void` | — | Modal closed |
96
+ | `onUpload` | `(file: File) => void` | — | User uploaded a photo |
97
+ | `onProcessing` | `(jobId: string) => void` | — | Try-on generation started |
98
+ | `onComplete` | `(result) => void` | — | Result ready: `{ jobId, imageUrl }` |
99
+ | `onError` | `(error) => void` | — | Error occurred: `{ message, code? }` |
180
100
 
181
101
  ---
182
102
 
@@ -184,28 +104,26 @@ import '@primestyleai/tryon';
184
104
 
185
105
  ### Button Styles
186
106
 
187
- Pass a JSON string to the `button-styles` attribute:
188
-
189
- ```html
190
- <primestyle-tryon
191
- api-key="ps_live_..."
192
- button-styles='{
193
- "backgroundColor": "#000000",
194
- "textColor": "#ffffff",
195
- "borderRadius": "50px",
196
- "padding": "16px 32px",
197
- "fontSize": "16px",
198
- "fontWeight": "700",
199
- "width": "100%",
200
- "border": "2px solid #333",
201
- "hoverBackgroundColor": "#222",
202
- "iconSize": "20px",
203
- "boxShadow": "0 4px 12px rgba(0,0,0,0.3)"
204
- }'
205
- ></primestyle-tryon>
107
+ ```jsx
108
+ <PrimeStyleTryon
109
+ productImage={product.image}
110
+ buttonStyles={{
111
+ backgroundColor: '#000000',
112
+ textColor: '#ffffff',
113
+ borderRadius: '50px',
114
+ padding: '16px 32px',
115
+ fontSize: '16px',
116
+ fontWeight: '700',
117
+ width: '100%',
118
+ border: '2px solid #333',
119
+ hoverBackgroundColor: '#222',
120
+ iconSize: '20px',
121
+ boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
122
+ }}
123
+ />
206
124
  ```
207
125
 
208
- **All button-styles options:**
126
+ **All ButtonStyles properties:**
209
127
 
210
128
  | Property | Description |
211
129
  |----------|-------------|
@@ -217,7 +135,7 @@ Pass a JSON string to the `button-styles` attribute:
217
135
  | `fontWeight` | Font weight |
218
136
  | `padding` | Inner spacing |
219
137
  | `border` | Border style |
220
- | `width` | Button width (e.g. `"100%"`, `"auto"`) |
138
+ | `width` | Button width (e.g. `"100%"`) |
221
139
  | `height` | Button height |
222
140
  | `hoverBackgroundColor` | Background on hover |
223
141
  | `hoverTextColor` | Text color on hover |
@@ -227,26 +145,25 @@ Pass a JSON string to the `button-styles` attribute:
227
145
 
228
146
  ### Modal Styles
229
147
 
230
- ```html
231
- <primestyle-tryon
232
- api-key="ps_live_..."
233
- modal-styles='{
234
- "backgroundColor": "#ffffff",
235
- "textColor": "#111111",
236
- "overlayColor": "rgba(0,0,0,0.7)",
237
- "borderRadius": "16px",
238
- "maxWidth": "520px",
239
- "headerBackgroundColor": "#f5f5f5",
240
- "headerTextColor": "#111111",
241
- "primaryButtonBackgroundColor": "#000000",
242
- "primaryButtonTextColor": "#ffffff",
243
- "loaderColor": "#000000",
244
- "uploadBorderColor": "#dddddd"
245
- }'
246
- ></primestyle-tryon>
148
+ ```jsx
149
+ <PrimeStyleTryon
150
+ productImage={product.image}
151
+ modalStyles={{
152
+ backgroundColor: '#ffffff',
153
+ textColor: '#111111',
154
+ overlayColor: 'rgba(0,0,0,0.7)',
155
+ borderRadius: '16px',
156
+ maxWidth: '520px',
157
+ headerBackgroundColor: '#f5f5f5',
158
+ headerTextColor: '#111111',
159
+ primaryButtonBackgroundColor: '#000000',
160
+ primaryButtonTextColor: '#ffffff',
161
+ loaderColor: '#000000',
162
+ }}
163
+ />
247
164
  ```
248
165
 
249
- **All modal-styles options:**
166
+ **All ModalStyles properties:**
250
167
 
251
168
  | Property | Description |
252
169
  |----------|-------------|
@@ -254,8 +171,7 @@ Pass a JSON string to the `button-styles` attribute:
254
171
  | `backgroundColor` | Modal background |
255
172
  | `textColor` | Modal text color |
256
173
  | `borderRadius` | Modal corner rounding |
257
- | `width` | Modal width |
258
- | `maxWidth` | Modal max width |
174
+ | `width` / `maxWidth` | Modal dimensions |
259
175
  | `fontFamily` | Modal font stack |
260
176
  | `headerBackgroundColor` | Header section background |
261
177
  | `headerTextColor` | Header title color |
@@ -270,159 +186,46 @@ Pass a JSON string to the `button-styles` attribute:
270
186
  | `loaderColor` | Loading spinner color |
271
187
  | `resultBorderRadius` | Result image corner rounding |
272
188
 
273
- ### CSS Custom Properties
274
-
275
- For deeper control, set CSS custom properties on the element:
276
-
277
- ```css
278
- primestyle-tryon {
279
- --ps-primary: #e63946;
280
- --ps-primary-hover: #c1121f;
281
- --ps-bg: #1a1a2e;
282
- --ps-text: #edf2f4;
283
- --ps-border: #444;
284
- --ps-radius: 16px;
285
- --ps-font: 'Inter', sans-serif;
286
- --ps-overlay: rgba(0, 0, 0, 0.8);
287
- }
288
- ```
289
-
290
- ### Programmatic Styling
291
-
292
- ```javascript
293
- const tryon = document.querySelector('primestyle-tryon');
294
-
295
- tryon.setButtonStyles({
296
- backgroundColor: '#e63946',
297
- textColor: '#ffffff',
298
- borderRadius: '50px',
299
- width: '100%',
300
- });
301
-
302
- tryon.setModalStyles({
303
- backgroundColor: '#1a1a2e',
304
- textColor: '#edf2f4',
305
- loaderColor: '#e63946',
306
- });
307
- ```
308
-
309
189
  ---
310
190
 
311
- ## Events
191
+ ## Callbacks
312
192
 
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
- });
338
-
339
- tryon.addEventListener('ps:close', () => {
340
- console.log('Modal closed');
341
- });
342
-
343
- tryon.addEventListener('ps:product-detected', (e) => {
344
- console.log('Auto-detected product image:', e.detail.imageUrl);
345
- });
346
- ```
347
-
348
- | Event | Detail | Description |
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 |
357
-
358
- ---
359
-
360
- ## JavaScript API
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
375
-
376
- ```javascript
377
- import { ApiClient } from '@primestyleai/tryon';
378
-
379
- const client = new ApiClient('ps_live_your_key');
380
-
381
- // Submit a try-on
382
- const { jobId, tokensDeducted, newBalance } = await client.submitTryOn(
383
- modelImageBase64, // User's photo (base64 data URL)
384
- garmentImageUrl // Product image URL
385
- );
386
-
387
- // Poll for status
388
- const status = await client.getStatus(jobId);
389
- // status.status: 'processing' | 'completed' | 'failed'
390
- // status.imageUrl: result URL when completed
391
- ```
392
-
393
- ### Real-Time Updates via SSE
394
-
395
- ```javascript
396
- import { ApiClient, SseClient } from '@primestyleai/tryon';
397
-
398
- const client = new ApiClient('ps_live_your_key');
399
- const sse = new SseClient(client.getStreamUrl());
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
- });
193
+ ```jsx
194
+ <PrimeStyleTryon
195
+ productImage={product.image}
196
+ onOpen={() => {
197
+ analytics.track('tryon_opened');
198
+ }}
199
+ onUpload={(file) => {
200
+ console.log('Photo uploaded:', file.name);
201
+ }}
202
+ onProcessing={(jobId) => {
203
+ console.log('Processing:', jobId);
204
+ }}
205
+ onComplete={(result) => {
206
+ console.log('Result ready:', result.imageUrl);
207
+ analytics.track('tryon_completed', { jobId: result.jobId });
208
+ }}
209
+ onError={(error) => {
210
+ console.error('Try-on failed:', error.message);
211
+ // error.code: 'INSUFFICIENT_TOKENS' | 'API_ERROR' | etc.
212
+ }}
213
+ onClose={() => {
214
+ console.log('Modal closed');
215
+ }}
216
+ />
408
217
  ```
409
218
 
410
219
  ---
411
220
 
412
- ## Product Image Detection
413
-
414
- If you don't provide a `product-image` attribute, the SDK automatically tries to detect the product image from the page using:
221
+ ## Environment Variables
415
222
 
416
- 1. **Open Graph tags** `<meta property="og:image">`
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
223
+ | Variable | Required | Default | Description |
224
+ |----------|----------|---------|-------------|
225
+ | `NEXT_PUBLIC_PRIMESTYLE_API_KEY` | Yes | | Your PrimeStyle API key |
226
+ | `NEXT_PUBLIC_PRIMESTYLE_API_URL` | No | `https://api.primestyleai.com` | Custom API endpoint |
419
227
 
420
- You can also call it programmatically:
421
-
422
- ```javascript
423
- const tryon = document.querySelector('primestyle-tryon');
424
- const imageUrl = tryon.detectProduct();
425
- ```
228
+ The component reads these automatically — no need to pass them as props.
426
229
 
427
230
  ---
428
231
 
@@ -440,11 +243,13 @@ Manage your balance and purchase tokens at [primestyleai.com/dashboard/billing](
440
243
 
441
244
  If a try-on fails, tokens are **automatically refunded** to your account.
442
245
 
443
- **Check your balance programmatically** via the response from each try-on:
246
+ The `onComplete` callback includes token info:
444
247
 
445
- ```javascript
446
- const { tokensDeducted, newBalance } = await client.submitTryOn(model, garment);
447
- console.log(`Used ${tokensDeducted} tokens. Remaining: ${newBalance}`);
248
+ ```jsx
249
+ onComplete={(result) => {
250
+ // result.jobId the job ID
251
+ // result.imageUrl — the result image URL
252
+ }}
448
253
  ```
449
254
 
450
255
  ---
@@ -460,39 +265,63 @@ Create and manage your API keys at the [Developer Dashboard](https://primestylea
460
265
 
461
266
  ---
462
267
 
463
- ## Browser Support
268
+ ## Full Example
464
269
 
465
- Works in all modern browsers:
270
+ ```jsx
271
+ // app/product/[id]/page.tsx (Next.js App Router)
466
272
 
467
- - Chrome 67+
468
- - Firefox 63+
469
- - Safari 10.1+
470
- - Edge 79+
273
+ import { PrimeStyleTryon } from '@primestyleai/tryon/react';
471
274
 
472
- The SDK uses Web Components (Custom Elements v1) and Shadow DOM.
275
+ export default function ProductPage({ product }) {
276
+ return (
277
+ <div className="product-page">
278
+ <div className="product-gallery">
279
+ <img src={product.image} alt={product.name} />
280
+ </div>
281
+
282
+ <div className="product-info">
283
+ <h1>{product.name}</h1>
284
+ <p className="price">${product.price}</p>
285
+
286
+ {/* Virtual Try-On — reads API key from env */}
287
+ <PrimeStyleTryon
288
+ productImage={product.image}
289
+ buttonText="Try It On"
290
+ buttonStyles={{
291
+ width: '100%',
292
+ padding: '14px 24px',
293
+ borderRadius: '10px',
294
+ fontSize: '15px',
295
+ }}
296
+ onComplete={(result) => {
297
+ // Show success toast, track analytics, etc.
298
+ toast.success('Your try-on is ready!');
299
+ }}
300
+ onError={(error) => {
301
+ toast.error(error.message);
302
+ }}
303
+ />
304
+
305
+ <button className="add-to-cart">Add to Cart</button>
306
+ </div>
307
+ </div>
308
+ );
309
+ }
310
+ ```
473
311
 
474
312
  ---
475
313
 
476
- ## Framework Compatibility
314
+ ## Requirements
477
315
 
478
- | Framework | Support | Notes |
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 |
316
+ - React 18+
317
+ - Next.js 13+ (App Router or Pages Router)
489
318
 
490
319
  ---
491
320
 
492
321
  ## Need Help?
493
322
 
494
- - [Documentation](https://primestyleai.com/docs) — Full API reference
495
323
  - [Live Demo](https://primestyleai.com/developer/demo) — See it in action
324
+ - [Documentation](https://primestyleai.com/docs) — Full API reference
496
325
  - [Dashboard](https://primestyleai.com/dashboard/developer/keys) — Manage keys & tokens
497
326
  - [Contact](mailto:support@primestyleai.com) — We're here to help
498
327