Upload a selfie. Become a legend. Battle the world.
An open-source showcase demonstrating Cloudinary as a first-class citizen in a modern full-stack app: Next.js 16 + Supabase + Vercel.
Upload a photo, let Cloudinary's AI remove the background and composite you onto a football trading card, then battle other players' cards to earn XP and climb the leaderboard.
- Signed direct uploads — browser uploads straight to Cloudinary, signed server-side; the file never passes through Next.js
- AI background removal — Cloudinary's
e_background_removalcuts out the photo background, no third-party service needed - Dynamic image composition — a single Cloudinary transformation chain overlays the user's photo + 6 stat values onto a nation card template; no server-side image processing
- Async content moderation — Cloudinary AWS Rekognition runs after upload and calls back a webhook to approve or reject
f_auto/q_autodelivery — Cloudinary automatically serves WebP/AVIF at optimal quality- Supabase Realtime — live leaderboard and moderation status updates, no polling
- Next.js 16 App Router — Server Components, Server Actions,
proxy.tssession middleware
- Guest (anonymous) auth with Supabase Auth — minimal demo implementation, not production-ready (see auth docs)
- Avatar upload with AI background removal and face-crop circle clipping
- Card creation: pick a nation, upload a photo → get a Cloudinary-rendered trading card
- AI content moderation on every upload
- Card gallery and public card detail pages
- Battle arena: auto-matchmaking, 6-stat duel simulation, animated results
- XP and leveling — stats increase on level-up, card image regenerates automatically
- Live leaderboard via Supabase Realtime
| Framework | Next.js 16 (App Router, TypeScript, Turbopack) |
| Styling | Tailwind CSS v4 |
| Database + Auth | Supabase (Postgres, Auth, Realtime, RLS) |
| Media | Cloudinary |
| Deploy | Vercel |
Requirements: Node 22, pnpm, a free Cloudinary account, a Supabase project.
Everything runs on the Cloudinary free tier. The AWS Rekognition add-on (content moderation) is required and has a free quota — enable it in your Cloudinary dashboard under Add-ons.
Cloudinary folder mode: This app works with both Fixed and Dynamic folder modes. All uploads use explicit
public_idpaths and includeasset_folderfor Media Library organisation. The one manual step: upload card templates withpnpm upload-templates --dir <path>— never upload them via the dashboard (auto-generated UUIDs break the card composition URLs). See docs/cloudinary.md.
git clone https://github.com/your-org/kickoff-cards
cd kickoff-cards
nvm use
pnpm install
cp .env.example .env.local
# fill in .env.local with your Cloudinary and Supabase credentials
pnpm devRequired Supabase dashboard step: Authentication → Sign In / Providers → enable Allow anonymous sign-ins. The app won't let anyone in without this.
See docs/getting-started.md for the full setup guide including Supabase schema, Cloudinary add-on setup, and the local webhook tunnel.
- Getting started
- Architecture
- Cloudinary integration ← start here for the Cloudinary details
- Data model
- Deployment
Feature docs: Authentication · Card creation · Moderation · Battles & leveling · Gallery & leaderboard
pnpm test # Vitest unit tests
pnpm lint # ESLint
pnpm build # TypeScript check + production buildMIT