Style a profile photo with Gemini. Pick a theme, upload an image, download the result.
Live: https://profilepop.liteshademedia.com (password protected)
- Next.js (App Router)
- Gemini image model via
@google/genai - Tailwind CSS
- Cloudflare Workers via
@opennextjs/cloudflare
- Install dependencies:
npm install- Copy the env file and add your Gemini API key:
cp .env.example .env.local- Run the app:
npm run devOpen http://localhost:3000.
Locally, Basic Auth is skipped unless you set SITE_PASSWORD in .env.local.
- Choose a visual theme (Anime, Neon Night, Oil Studio, and more).
- Upload a JPG, PNG, or WebP profile photo (max 8MB).
- Hit Pop it — the app sends your image and a theme prompt to Gemini.
- Download the styled portrait.
API route: POST /api/generate with multipart/form-data fields themeId and image.
Worker name: profilepop
Custom domain: profilepop.liteshademedia.com
- Create a Cloudflare API token with Workers Scripts Edit, Account Settings Read, and Zone DNS Edit for
liteshademedia.com. - Add GitHub repo secrets:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_ID
- Deploy once (local or via Actions), then set Worker secrets:
npx wrangler secret put GEMINI_API_KEY
npx wrangler secret put SITE_PASSWORD
# optional:
# npx wrangler secret put SITE_USERNAMEDefault Basic Auth username is portfolio when SITE_USERNAME is unset.
npm run deployPushes to master run .github/workflows/deploy.yml, which builds with OpenNext and deploys the Worker. App secrets (GEMINI_API_KEY, SITE_PASSWORD) stay on the Worker — they are not set by the workflow.
npm run preview