@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 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):**
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
- ```javascript
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
- // The <primestyle-tryon> custom element is now registered globally
54
+ ```env
55
+ NEXT_PUBLIC_PRIMESTYLE_API_KEY=ps_live_your_key_here
111
56
  ```
112
57
 
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,38 @@ 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 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
- 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>
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 button-styles options:**
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%"`, `"auto"`) |
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
- ```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>
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 modal-styles options:**
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 width |
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 Properties
190
+ ### Tailwind CSS / Custom Classes
274
191
 
275
- For deeper control, set CSS custom properties on the element:
192
+ Use the `classNames` prop to style any element with Tailwind utilities or your own CSS classes:
276
193
 
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
- }
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
- ### Programmatic Styling
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
- ```javascript
293
- const tryon = document.querySelector('primestyle-tryon');
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
- tryon.setButtonStyles({
296
- backgroundColor: '#e63946',
297
- textColor: '#ffffff',
298
- borderRadius: '50px',
299
- width: '100%',
300
- });
257
+ /* Override the modal */
258
+ .ps-tryon-modal {
259
+ background: #fff;
260
+ color: #111;
261
+ border-radius: 16px;
262
+ }
301
263
 
302
- tryon.setModalStyles({
303
- backgroundColor: '#1a1a2e',
304
- textColor: '#edf2f4',
305
- loaderColor: '#e63946',
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
- tryon.addEventListener('ps:close', () => {
340
- console.log('Modal closed');
341
- });
273
+ You can mix all three styling methods — they layer on top of each other:
342
274
 
343
- tryon.addEventListener('ps:product-detected', (e) => {
344
- console.log('Auto-detected product image:', e.detail.imageUrl);
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
- | 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 |
286
+ Priority: Tailwind/classNames classes > CSS variables (buttonStyles/modalStyles) > default styles.
357
287
 
358
288
  ---
359
289
 
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
290
+ ## Callbacks
375
291
 
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
- });
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
- ## Product Image Detection
320
+ ## Environment Variables
413
321
 
414
- If you don't provide a `product-image` attribute, the SDK automatically tries to detect the product image from the page using:
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
- 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
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
- **Check your balance programmatically** via the response from each try-on:
345
+ The `onComplete` callback includes token info:
444
346
 
445
- ```javascript
446
- const { tokensDeducted, newBalance } = await client.submitTryOn(model, garment);
447
- console.log(`Used ${tokensDeducted} tokens. Remaining: ${newBalance}`);
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
- ## Browser Support
367
+ ## Full Example
464
368
 
465
- Works in all modern browsers:
369
+ ```jsx
370
+ // app/product/[id]/page.tsx (Next.js App Router)
466
371
 
467
- - Chrome 67+
468
- - Firefox 63+
469
- - Safari 10.1+
470
- - Edge 79+
372
+ import { PrimeStyleTryon } from '@primestyleai/tryon/react';
471
373
 
472
- The SDK uses Web Components (Custom Elements v1) and Shadow DOM.
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
- ## Framework Compatibility
413
+ ## Requirements
477
414
 
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 |
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