A Next.js application that generates personalized tarot cards from Twitter avatars using Google Gemini AI. Users enter their Twitter handle, and the system creates a mystical tarot card featuring their portrait.
- π¨ AI-Powered Image Generation - Uses Google Gemini to create tarot cards from Twitter avatars
- π¦ Twitter Integration - Fetches avatars via Unavatar.io (no Twitter API needed)
- πΎ Handle Tracking - Stores Twitter handles in Supabase database
- π± Responsive Design - Beautiful UI built with Tailwind CSS
- π Social Sharing - Share tarot cards on Twitter
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- AI: Google Gemini 2.5 Flash Image Preview
- Database: Supabase (PostgreSQL)
- Avatar Service: Unavatar.io
- Node.js 18+ and npm/yarn
- Google Gemini API key (Get one here)
- Supabase account (Sign up here)
-
Clone or navigate to the project:
cd Parasol-Tarot -
Install dependencies:
npm install
-
Set up environment variables:
cp .env.example .env.local
Then edit
.env.localwith your credentials:GEMINI_API_KEY=your_gemini_api_key NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=your_supabase_publishable_key NEXT_PUBLIC_URL=http://localhost:3000 NEXT_PUBLIC_BRAND_NAME=Your Event Name
-
Set up Supabase database:
- Create a new Supabase project
- Run the SQL from
supabase/schema.sqlin the SQL Editor - This creates the
twitter_handlestable with proper indexes and policies
-
Run the development server:
npm run dev
-
Open http://localhost:3000 in your browser
Edit tailwind.config.ts:
colors: {
'brand-primary': '#YOUR_COLOR',
'brand-secondary': '#YOUR_COLOR',
// ...
}Also update BRAND_COLORS in lib/gemini-api.ts to match.
Set NEXT_PUBLIC_BRAND_NAME in your .env.local file, or update it in the code.
Edit the components in components/ and app/page.tsx to change UI text and messaging.
Parasol-Tarot/
βββ app/
β βββ api/
β β βββ generate-outfit/ # Main tarot card generation endpoint
β β βββ resolve-identity/ # Twitter avatar fetching
β β βββ og-image/ # Open Graph images
β βββ outfit/[handle]/ # Shareable tarot card pages
β βββ layout.tsx # Root layout
β βββ page.tsx # Main page
β βββ globals.css # Global styles
βββ components/
β βββ HandleInput.tsx # Twitter handle input
β βββ LoadingState.tsx # Loading animations
β βββ PlatformSelector.tsx # Platform UI
β βββ ResultsDisplay.tsx # Results display
βββ lib/
β βββ gemini-api.ts # Gemini API client
β βββ supabase.ts # Supabase client
β βββ utils.ts # Utility functions
βββ supabase/
β βββ schema.sql # Database schema
βββ package.json
Fetches Twitter avatar for a handle.
Request:
{
"handle": "elonmusk",
"platform": "twitter"
}Response:
{
"success": true,
"profile": {
"id": "elonmusk",
"displayName": "elonmusk",
"imageUrl": "https://..."
}
}Generates a tarot card from an avatar image.
Request:
{
"imageUrl": "https://avatar-url.com/image.jpg",
"username": "elonmusk"
}Response:
{
"success": true,
"image": "base64_image_data"
}Returns tarot card image for Open Graph/social sharing (currently returns 404 as images are not cached).
- Push your code to GitHub
- Import project in Vercel
- Add environment variables in Vercel dashboard
- Deploy!
The app can be deployed to any platform that supports Next.js:
- Netlify
- Railway
- AWS Amplify
- etc.
Make sure to set all environment variables in your deployment platform.
- User enters Twitter handle β Frontend calls
/api/resolve-identity - Fetch avatar β Uses Unavatar.io to get profile picture
- Generate tarot card β Sends image to Gemini API for background removal and processing
- Add glow effect β Sharp adds a luminous glow around the portrait
- Composite on card β Portrait is composited onto tarot card background
- Save handle β Stores Twitter handle in Supabase database
- Display result β Shows generated tarot card with download/share options
| Variable | Description | Required |
|---|---|---|
GEMINI_API_KEY |
Google Gemini API key | Yes |
NEXT_PUBLIC_SUPABASE_URL |
Supabase project URL | Yes |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY |
Supabase publishable/default key | Yes |
NEXT_PUBLIC_URL |
Your app URL (for OG images) | Yes |
NEXT_PUBLIC_BRAND_NAME |
Brand/event name | No |
- Make sure you've set the environment variable in
.env.local - Restart your dev server after adding env vars
- The Twitter account might be private or suspended
- Try a different handle
- Use the upload feature as a fallback
- Check your Gemini API key is valid
- Check API quota/limits
- Try again (sometimes API has temporary issues)
MIT
Built with: