DATABASE_URL setThe merch UI is served by zooly-app under /merch, and merch admin under /admin/merch (the former apps/zooly-merch/ and apps/zooly-merch-admin/ Vite wrappers have been removed):
# Merch UI, merch admin, and backend API
cd apps/zooly-app && npm run dev # Port 3004
Visit http://localhost:3004/merch/teststore/lexnour to see the test campaign.
Merch admin (campaign builder) is http://localhost:3004/admin/merch. For the Benchmark tab, open http://localhost:3004/admin/merch/benchmark (admin login required). See Image Generation Benchmark.
The merch app requires campaign/product data in the database. Run the seed script:
DATABASE_URL="postgresql://postgres:admin@localhost:5432/zoolylocal" \
npx tsx packages/db/src/seed/merch-seed.ts
This creates 3 test campaigns:
| Campaign | URL | Products |
|---|---|---|
| Lexnour | /teststore/lexnour | T-Shirt ($69), Hoodie ($109) |
| LAS VEGAS ACES | /Las%20Vegas%20Aces/las-vegas-aces | Team Tee ($45), Pro Hoodie ($85), Championship Plaque ($59) |
| Plaque | /plaque/plaque | T-Shirt ($69), Hoodie ($109), Plaque ($39) |
Set in apps/zooly-app/.env.local:
| Variable | Purpose |
|---|---|
ALLOWED_DOMAINS_CORS | Comma-separated allowed CORS origins for other frontends. The merch UI and merch admin are same-origin with the API |
STRIPE_SECRET_KEY | Stripe server key (sk_test_...) |
STRIPE_PUBLISHABLE_KEY | Stripe publishable key (pk_test_...) |
SENDGRID_API_KEY | SendGrid email delivery |
NEXT_PUBLIC_UI_HOST | Merch experience host for email links, without a path (email code appends /merch/...; use http://localhost:3004 locally) |
SUPPORT_EMAIL_ADDRESSES | Comma-separated; first used as "from" address |
MERCH_MOCKUP_MODE | composite (default) or ai-tryon |
FAL_KEY | fal.ai API key for opt-in BRIA RMBG 2.0 background removal, the Krea 3 image model, and legacy generation paths |
AWS_ACCESS_KEY_ID | S3 access |
AWS_SECRET_ACCESS_KEY | S3 access |
AWS_REGION | S3 region |
AWS_BUCKET_NAME | S3 bucket |
DATABASE_URL | PostgreSQL connection |
Production: merch.zooly.ai reverse proxies to app.zooly.ai/merch.
http://localhost:3004/merch shows 3 campaign cardshttp://localhost:3004/merch/teststore/lexnour shows hero, CTAs, legal footer/create): Logarithmic progress + email capture + carousel during generation; then art selection (if multiple candidates) and cart view on the same URL; reselfie via overlay; BUY from art adds to cart on-page, BUY from cart continues to shipping4242 4242 4242 4242)| Issue | Fix |
|---|---|
| CORS errors | Merch UI and merch admin are same-origin with the API. Add an origin to ALLOWED_DOMAINS_CORS only for a different frontend that calls zooly-app |
| Images not loading | S3 assets from seed don't exist locally; expected behavior |
| Stripe errors | Ensure STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY are set |
| Emails not sending | Check SENDGRID_API_KEY, SUPPORT_EMAIL_ADDRESSES, NEXT_PUBLIC_UI_HOST |
| Camera not working | HTTPS required for getUserMedia in most browsers; use localhost or ngrok |