@primestyleai/tryon
v3.4.2
Published
PrimeStyle Virtual Try-On SDK — React component & Web Component
Maintainers
Readme
How It Works
- Customer clicks the "Virtual Try-On" button on your product page
- They upload a photo of themselves
- PrimeStyle AI generates a realistic try-on image in ~15 seconds
- Customer sees how the garment looks on them before buying
The entire flow happens inside a beautiful modal — no redirects, no iframes.
Quick Start
1. Install
npm install @primestyleai/tryon2. Set Your API Key
Get your key from the Developer Dashboard and add it to your .env.local:
NEXT_PUBLIC_PRIMESTYLE_API_KEY=ps_live_your_key_here3. Use the Component
import { PrimeStyleTryon } from '@primestyleai/tryon/react';
function ProductPage({ product }) {
return (
<div>
<h1>{product.name}</h1>
<img src={product.image} alt={product.name} />
<PrimeStyleTryon
productImage={product.image}
buttonText="Try It On"
/>
</div>
);
}That's it. No API key prop needed — the component reads it from your environment automatically.
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| productImage | string | required | URL of the garment image |
| buttonText | string | "Virtual Try-On" | Text on the trigger button |
| apiUrl | string | NEXT_PUBLIC_PRIMESTYLE_API_URL or production | API endpoint override |
| showPoweredBy | boolean | true | Show "Powered by PrimeStyle AI" in modal |
| buttonStyles | ButtonStyles | {} | Customize button via style props |
| modalStyles | ModalStyles | {} | Customize modal via style props |
| classNames | PrimeStyleClassNames | {} | Override element classes (Tailwind, CSS) |
| className | string | — | Additional CSS class on wrapper |
| style | CSSProperties | — | Inline styles on wrapper |
| onOpen | () => void | — | Modal opened |
| onClose | () => void | — | Modal closed |
| onUpload | (file: File) => void | — | User uploaded a photo |
| onProcessing | (jobId: string) => void | — | Try-on generation started |
| onComplete | (result) => void | — | Result ready: { jobId, imageUrl } |
| onError | (error) => void | — | Error occurred: { message, code? } |
Customization
Button Styles
<PrimeStyleTryon
productImage={product.image}
buttonStyles={{
backgroundColor: '#000000',
textColor: '#ffffff',
borderRadius: '50px',
padding: '16px 32px',
fontSize: '16px',
fontWeight: '700',
width: '100%',
border: '2px solid #333',
hoverBackgroundColor: '#222',
iconSize: '20px',
boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
}}
/>All ButtonStyles properties:
| Property | Description |
|----------|-------------|
| backgroundColor | Button background color |
| textColor | Button text color |
| borderRadius | Corner rounding |
| fontSize | Text size |
| fontFamily | Font stack |
| fontWeight | Font weight |
| padding | Inner spacing |
| border | Border style |
| width | Button width (e.g. "100%") |
| height | Button height |
| hoverBackgroundColor | Background on hover |
| hoverTextColor | Text color on hover |
| iconSize | Camera icon size |
| iconColor | Camera icon color |
| boxShadow | Shadow effect |
Modal Styles
<PrimeStyleTryon
productImage={product.image}
modalStyles={{
backgroundColor: '#ffffff',
textColor: '#111111',
overlayColor: 'rgba(0,0,0,0.7)',
borderRadius: '16px',
maxWidth: '520px',
headerBackgroundColor: '#f5f5f5',
headerTextColor: '#111111',
primaryButtonBackgroundColor: '#000000',
primaryButtonTextColor: '#ffffff',
loaderColor: '#000000',
}}
/>All ModalStyles properties:
| Property | Description |
|----------|-------------|
| overlayColor | Background overlay color |
| backgroundColor | Modal background |
| textColor | Modal text color |
| borderRadius | Modal corner rounding |
| width / maxWidth | Modal dimensions |
| fontFamily | Modal font stack |
| headerBackgroundColor | Header section background |
| headerTextColor | Header title color |
| closeButtonColor | Close (X) button color |
| uploadBorderColor | Upload drop zone border |
| uploadBackgroundColor | Upload zone background |
| uploadTextColor | Upload zone text |
| uploadIconColor | Upload icon color |
| primaryButtonBackgroundColor | Submit / download button background |
| primaryButtonTextColor | Submit / download button text |
| primaryButtonBorderRadius | Submit button rounding |
| loaderColor | Loading spinner color |
| resultBorderRadius | Result image corner rounding |
Tailwind CSS / Custom Classes
Use the classNames prop to style any element with Tailwind utilities or your own CSS classes:
<PrimeStyleTryon
productImage={product.image}
classNames={{
button: "bg-black text-white rounded-full px-8 py-4 hover:bg-gray-800",
modal: "bg-white rounded-2xl shadow-2xl",
header: "bg-gray-50 border-b border-gray-200",
title: "text-gray-900 text-lg",
closeButton: "text-gray-400 hover:text-gray-600",
body: "p-6",
uploadZone: "border-2 border-dashed border-gray-300 rounded-xl p-10 hover:border-blue-400",
uploadText: "text-gray-700",
submitButton: "bg-blue-600 text-white rounded-lg hover:bg-blue-700",
downloadButton: "bg-green-600 text-white rounded-lg",
retryButton: "bg-gray-100 text-gray-700 border border-gray-300",
}}
/>All classNames keys:
| Key | Element |
|-----|---------|
| root | Root wrapper <div> |
| button | Trigger button |
| overlay | Modal backdrop overlay |
| modal | Modal container |
| header | Modal header bar |
| title | Modal title text |
| closeButton | Close (X) button |
| body | Modal body area |
| uploadZone | Upload drop zone |
| uploadText | "Drop your photo..." text |
| uploadHint | File type hint text |
| preview | Preview image container |
| previewImage | Preview <img> element |
| removeButton | Remove preview button |
| submitButton | "Try It On" / "Try Again" button |
| spinner | Loading spinner |
| processingText | "Generating..." text |
| processingSubText | "This usually takes..." text |
| result | Result container |
| resultImage | Result <img> element |
| resultActions | Download/retry button row |
| downloadButton | Download button |
| retryButton | "Try Another" button |
| error | Error container |
| errorText | Error message text |
| poweredBy | Footer text |
Normal CSS
All elements use ps-tryon-* class names that you can target directly in your CSS:
/* Override the trigger button */
.ps-tryon-btn {
background: #000;
color: #fff;
border-radius: 50px;
padding: 16px 32px;
}
/* Override the modal */
.ps-tryon-modal {
background: #fff;
color: #111;
border-radius: 16px;
}
/* Override the submit button */
.ps-tryon-submit {
background: #2563eb;
color: #fff;
}Combining Approaches
You can mix all three styling methods — they layer on top of each other:
<PrimeStyleTryon
productImage={product.image}
// 1. Style props (CSS variables)
buttonStyles={{ width: '100%' }}
// 2. Tailwind classes
classNames={{ button: "rounded-full font-bold" }}
// 3. Normal CSS targets .ps-tryon-btn automatically
/>Priority: Tailwind/classNames classes > CSS variables (buttonStyles/modalStyles) > default styles.
Callbacks
<PrimeStyleTryon
productImage={product.image}
onOpen={() => {
analytics.track('tryon_opened');
}}
onUpload={(file) => {
console.log('Photo uploaded:', file.name);
}}
onProcessing={(jobId) => {
console.log('Processing:', jobId);
}}
onComplete={(result) => {
console.log('Result ready:', result.imageUrl);
analytics.track('tryon_completed', { jobId: result.jobId });
}}
onError={(error) => {
console.error('Try-on failed:', error.message);
// error.code: 'INSUFFICIENT_TOKENS' | 'API_ERROR' | etc.
}}
onClose={() => {
console.log('Modal closed');
}}
/>Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| NEXT_PUBLIC_PRIMESTYLE_API_KEY | Yes | — | Your PrimeStyle API key |
| NEXT_PUBLIC_PRIMESTYLE_API_URL | No | https://myaifitting.com | Custom API endpoint |
The component reads these automatically — no need to pass them as props.
Tokens & Pricing
Each virtual try-on consumes tokens from your account balance.
| | | |---|---| | Free trial | Tokens included on signup | | Token packs | Pay-as-you-go, never expire | | Monthly plans | Volume discounts for high-traffic stores |
Manage your balance and purchase tokens at primestyleai.com/developer/dashboard/billing.
If a try-on fails, tokens are automatically refunded to your account.
The onComplete callback includes token info:
onComplete={(result) => {
// result.jobId — the job ID
// result.imageUrl — the result image URL
}}API Key Management
Create and manage your API keys at the Developer Dashboard.
- Keys start with
ps_live_and are shown once at creation - Set allowed domains to restrict where your key can be used
- Revoke keys instantly if compromised
- Maximum 10 active keys per account
Full Example
// app/product/[id]/page.tsx (Next.js App Router)
import { PrimeStyleTryon } from '@primestyleai/tryon/react';
export default function ProductPage({ product }) {
return (
<div className="product-page">
<div className="product-gallery">
<img src={product.image} alt={product.name} />
</div>
<div className="product-info">
<h1>{product.name}</h1>
<p className="price">${product.price}</p>
{/* Virtual Try-On — reads API key from env */}
<PrimeStyleTryon
productImage={product.image}
buttonText="Try It On"
buttonStyles={{
width: '100%',
padding: '14px 24px',
borderRadius: '10px',
fontSize: '15px',
}}
onComplete={(result) => {
// Show success toast, track analytics, etc.
toast.success('Your try-on is ready!');
}}
onError={(error) => {
toast.error(error.message);
}}
/>
<button className="add-to-cart">Add to Cart</button>
</div>
</div>
);
}Requirements
- React 18+
- Next.js 13+ (App Router or Pages Router)
Need Help?
- Live Demo — See it in action
- Documentation — Full API reference
- Dashboard — Manage keys & tokens
- Contact — We're here to help
