Code Examples
Real-world integration examples for popular platforms and frameworks.
All Examples
Shopify
E-commerceLiquid template integration with theme blocks
React
FrontendModern React app with hooks and TypeScript
Next.js
Full-stackServer-side rendering with API routes
WooCommerce
E-commerceWordPress plugin integration
React Native
MobileMobile app integration
Node.js Backend
BackendServer-side API integration
Shopify Integration
Add virtual try-on to your Shopify store using Liquid templates.
snippets/willitfit-button.liquidliquid
1 {%- comment -%} 2 WillItFit Virtual Try-On Button 3 Add this to snippets/willitfit-button.liquid 4 {%- endcomment -%} 5 6 <div class="willitfit-container" 7 data-product-id="{{ product.id }}" 8 data-product-image="{{ product.featured_image | image_url: width: 800 }}" 9 data-product-title="{{ product.title | escape }}"> 10 11 <button type="button" 12 class="btn btn--full btn--secondary willitfit-trigger" 13 aria-label="Try on {{ product.title }} virtually"> 14 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 15 <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/> 16 </svg> 17 Virtual Try-On 18 </button> 19 </div> 20 21 <script> 22 document.addEventListener('DOMContentLoaded', function() { 23 const container = document.querySelector('.willitfit-container'); 24 if (!container) return; 25 26 const productId = container.dataset.productId; 27 const productImage = container.dataset.productImage; 28 29 container.querySelector('.willitfit-trigger').addEventListener('click', function() { 30 // Open WillItFit widget 31 window.WillItFitWidget.open({ 32 productId: productId, 33 productImage: productImage, 34 onComplete: function(result) { 35 console.log('Try-on completed:', result); 36 } 37 }); 38 }); 39 }); 40 </script>
React Integration
Build a custom try-on component using React hooks.
useTryOn.tstypescript
1 import { useState, useCallback } from 'react'; 2 import { WillItFit } from '@willitfit/sdk'; 3 4 const client = new WillItFit({ 5 apiKey: process.env.NEXT_PUBLIC_WILLITFIT_API_KEY, 6 }); 7 8 interface TryOnResult { 9 resultImageUrl: string; 10 fitScore: number; 11 recommendations: string[]; 12 } 13 14 export function useTryOn() { 15 const [loading, setLoading] = useState(false); 16 const [error, setError] = useState<string | null>(null); 17 const [result, setResult] = useState<TryOnResult | null>(null); 18 19 const tryOn = useCallback(async ( 20 productImageUrl: string, 21 userPhoto: string, 22 category?: string 23 ) => { 24 setLoading(true); 25 setError(null); 26 27 try { 28 const response = await client.tryOn.create({ 29 productImageUrl, 30 userPhoto, 31 productCategory: category, 32 }); 33 34 setResult({ 35 resultImageUrl: response.resultImageUrl, 36 fitScore: response.fitScore, 37 recommendations: response.recommendations || [], 38 }); 39 40 return response; 41 } catch (err) { 42 setError(err instanceof Error ? err.message : 'Try-on failed'); 43 throw err; 44 } finally { 45 setLoading(false); 46 } 47 }, []); 48 49 const reset = useCallback(() => { 50 setResult(null); 51 setError(null); 52 setLoading(false); 53 }, []); 54 55 return { tryOn, reset, loading, error, result }; 56 } 57 58 // Usage in component 59 export function TryOnButton({ productImageUrl, category }: Props) { 60 const [userPhoto, setUserPhoto] = useState<string | null>(null); 61 const { tryOn, loading, result, error, reset } = useTryOn(); 62 63 const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { 64 const file = e.target.files?.[0]; 65 if (file) { 66 const reader = new FileReader(); 67 reader.onload = (e) => { 68 setUserPhoto(e.target?.result as string); 69 }; 70 reader.readAsDataURL(file); 71 } 72 }; 73 74 const handleTryOn = async () => { 75 if (!userPhoto) return; 76 const base64 = userPhoto.split(',')[1]; 77 await tryOn(productImageUrl, base64, category); 78 }; 79 80 if (result) { 81 return ( 82 <div className="text-center"> 83 <img src={result.resultImageUrl} alt="Try-on result" /> 84 <p className="text-lg font-bold">Fit Score: {result.fitScore}%</p> 85 <button onClick={reset}>Try Another</button> 86 </div> 87 ); 88 } 89 90 return ( 91 <div> 92 <input type="file" accept="image/*" onChange={handleFileChange} /> 93 <button onClick={handleTryOn} disabled={!userPhoto || loading}> 94 {loading ? 'Processing...' : 'Try On'} 95 </button> 96 {error && <p className="text-red-500">{error}</p>} 97 </div> 98 ); 99 }
Next.js Integration
Server-side API route for secure key handling.
app/api/tryon/route.tstypescript
1 // app/api/tryon/route.ts 2 import { NextRequest, NextResponse } from 'next/server'; 3 import { WillItFit } from '@willitfit/sdk'; 4 5 const client = new WillItFit({ 6 apiKey: process.env.WILLITFIT_API_KEY!, // Server-side only 7 }); 8 9 export async function POST(request: NextRequest) { 10 try { 11 const body = await request.json(); 12 const { productImageUrl, userPhoto, category } = body; 13 14 // Validate input 15 if (!productImageUrl || !userPhoto) { 16 return NextResponse.json( 17 { error: 'Missing required fields' }, 18 { status: 400 } 19 ); 20 } 21 22 // Call WillItFit API 23 const result = await client.tryOn.create({ 24 productImageUrl, 25 userPhoto, 26 productCategory: category, 27 }); 28 29 return NextResponse.json({ success: true, result }); 30 } catch (error) { 31 console.error('Try-on error:', error); 32 return NextResponse.json( 33 { error: 'Try-on failed' }, 34 { status: 500 } 35 ); 36 } 37 }
WooCommerce Integration
Add virtual try-on to your WordPress/WooCommerce store.
willitfit-woocommerce.phpphp
1 <?php 2 /** 3 * Plugin Name: WillItFit Virtual Try-On 4 * Description: Add virtual try-on to WooCommerce products 5 * Version: 1.0.0 6 */ 7 8 class WillItFit_WooCommerce { 9 10 private $api_key; 11 private $api_url = 'https://api.willitfit.ai/v1'; 12 13 public function __construct() { 14 $this->api_key = get_option('willitfit_api_key'); 15 16 // Add button to product page 17 add_action('woocommerce_before_add_to_cart_button', [$this, 'render_tryon_button']); 18 19 // Enqueue scripts 20 add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']); 21 22 // AJAX handler 23 add_action('wp_ajax_willitfit_tryon', [$this, 'handle_tryon']); 24 add_action('wp_ajax_nopriv_willitfit_tryon', [$this, 'handle_tryon']); 25 } 26 27 public function render_tryon_button() { 28 global $product; 29 $image_url = wp_get_attachment_url($product->get_image_id()); 30 ?> 31 <div class="willitfit-container" data-product-image="<?php echo esc_url($image_url); ?>"> 32 <button type="button" class="button willitfit-trigger"> 33 🪄 Virtual Try-On 34 </button> 35 </div> 36 <div id="willitfit-modal" style="display: none;"> 37 <!-- Modal content --> 38 </div> 39 <?php 40 } 41 42 public function enqueue_scripts() { 43 if (is_product()) { 44 wp_enqueue_script( 45 'willitfit-widget', 46 'https://cdn.willitfit.ai/widget.js', 47 [], 48 '1.0.0', 49 true 50 ); 51 52 wp_localize_script('willitfit-widget', 'willitfit_config', [ 53 'api_key' => $this->api_key, 54 'ajax_url' => admin_url('admin-ajax.php'), 55 'nonce' => wp_create_nonce('willitfit_nonce'), 56 ]); 57 } 58 } 59 60 public function handle_tryon() { 61 check_ajax_referer('willitfit_nonce', 'nonce'); 62 63 $response = wp_remote_post($this->api_url . '/tryon', [ 64 'headers' => [ 65 'Authorization' => 'Bearer ' . $this->api_key, 66 'Content-Type' => 'application/json', 67 ], 68 'body' => json_encode([ 69 'productImageUrl' => $_POST['product_image'], 70 'userPhoto' => $_POST['user_photo'], 71 ]), 72 ]); 73 74 wp_send_json(json_decode(wp_remote_retrieve_body($response))); 75 } 76 } 77 78 new WillItFit_WooCommerce();