AI-powered Virtual Try-On widget for Shopify stores. Customers upload a photo and see themselves wearing your products — powered by Gemini / Vertex AI image generation.
┌──────────────────────────────────────────────────┐
│ Shopify Store │
│ ┌────────────────┐ ┌───────────────────────┐ │
│ │ Product Page │ │ Cart Page │ │
│ │ {% render │ │ {% render │ │
│ │ 'tryit- │ │ 'tryit-cart' %} │ │
│ │ product' %} │ │ │ │
│ └──────┬─────────┘ └──────────┬────────────┘ │
│ │ iframe │ iframe │
└─────────┼─────────────────────────┼───────────────┘
▼ ▼
┌──────────────────────────────────────────────────┐
│ TryIt App (Next.js) │
│ │
│ /widget/product ← product-page iframe │
│ /widget/cart ← cart-page iframe │
│ │
│ /api/generate ← orchestrator → provider │
│ /api/upload ← direct GCS upload │
│ /api/health ← provider health checks │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Provider Registry │ │
│ │ ├── vertex (Vertex AI) │ │
│ │ └── your_custom_provider ... │ │
│ └─────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
# 1. Install deps
npm install
# 2. Copy env and fill in your keys
cp .env.example .env
# 3. Run dev server
npm run devOpen http://localhost:3000 to see the landing page. Demo widgets at /widget/product and /widget/cart.
On any product page, a button opens a modal with an iframe. The garment image is passed automatically. Customer uploads their photo → generates a try-on image.
On the cart page, a button opens a modal showing all cart items. Customer selects which items to try, uploads their photo → generates try-on images.
- Copy
shopify/snippets/tryit-product.liquid→ your theme'ssnippets/folder - Copy
shopify/snippets/tryit-cart.liquid→ your theme'ssnippets/folder - In your product template:
{% render 'tryit-product', product: product %} - In your cart template:
{% render 'tryit-cart' %} - Update
tryit_baseURL in both snippets to your deployed app URL
| Method | Path | Description |
|---|---|---|
| POST | /api/generate |
Run virtual try-on |
| POST | /api/upload |
Upload image to GCS |
| GET | /api/health |
Provider health checks |
{
"personImages": ["data:image/jpeg;base64,..."],
"garmentImages": ["data:image/jpeg;base64,..."],
"prompt": "casual summer look",
"provider": "vertex",
"mode": "upper_body"
}- Create
src/lib/providers/my-provider.ts - Implement the
ImageProviderinterface:
import type { ImageProvider, GenerationRequest, GenerationResult } from "./base";
export class MyProvider implements ImageProvider {
readonly name = "my_provider";
async generate(req: GenerationRequest): Promise<GenerationResult[]> {
// Your implementation here
}
async healthCheck(): Promise<boolean> {
return true;
}
}- Register it in
src/lib/providers/index.ts:
import { MyProvider } from "./my-provider";
// inside bootProviders():
ProviderRegistry.register(new MyProvider());That's it. It's now available via provider: "my_provider" in API calls and widget params.
- Next.js 15 (App Router) + TypeScript
- Tailwind CSS for widget styling
- Google Cloud Storage for image storage (direct upload, no presigned URLs)
- Vertex AI for image generation (Virtual Try-On API)
- Zod for request validation