76834b3d21c853af500afd06e39a8f08c0927a1f
ExposedGays
100% free gay cruising map + chat + spots directory + sex shop. No subscriptions ever.
Domain: exposedgays.com
Quick Start
npm install
cp .env.example .env.local
# Edit .env.local with your Supabase keys (optional for local demo — mock data works offline)
npm run dev
Features
| Feature | Status |
|---|---|
| Real-time cruising map (Leaflet + OSM) | ✅ Mock data + Supabase-ready |
| User clustering + position badges | ✅ |
| Map filters (age, position, kinks, PrEP) | ✅ |
| Cruiser Cards + Profile popup | ✅ |
| Instant chat + city chat + DMs + groups | ✅ Mock + Supabase schema |
| Cruising spot directory | ✅ |
| Shop (affiliate links, local cart) | ✅ |
| Age verification gate (Florida-compliant) | ✅ |
| Vanilla mode blur toggle | ✅ |
| Dark mode, mobile-first, PWA manifest | ✅ |
| Anonymous browsing + optional profile | ✅ |
Tech Stack
- Next.js 15 App Router + TypeScript
- Tailwind CSS + shadcn/ui components
- React-Leaflet + OpenStreetMap tiles
- Supabase — Auth, Postgres + PostGIS, Realtime, Storage
- Zustand — localStorage cart
Project Structure
exposedgays/
├── public/
│ └── manifest.json # PWA manifest
├── src/
│ ├── app/
│ │ ├── layout.tsx # Root layout + nav
│ │ ├── page.tsx # Map (home)
│ │ ├── shop/page.tsx # Sex shop
│ │ ├── chat/page.tsx # City chat + DMs
│ │ ├── spots/page.tsx # Spot directory
│ │ └── profile/page.tsx # User profile editor
│ ├── components/
│ │ ├── AgeGate.tsx # 18+ DOB verification
│ │ ├── Map.tsx # Interactive cruising map
│ │ ├── Shop.tsx # Product grid + cart
│ │ ├── Nav.tsx # Top/bottom nav with Shop link
│ │ ├── ChatPanel.tsx # Real-time chat UI
│ │ ├── CruiserCard.tsx # Squirt-style cruiser cards
│ │ ├── ProfilePopup.tsx # Tap icon → profile modal
│ │ ├── SpotDirectory.tsx # Spot listings + search
│ │ └── ui/ # shadcn components
│ ├── lib/
│ │ ├── products.ts # Dummy shop inventory
│ │ ├── cart.ts # Zustand localStorage cart
│ │ ├── mock-data.ts # Demo cruisers + spots
│ │ └── supabase/ # Supabase client helpers
│ └── types/index.ts
├── supabase/
│ └── schema.sql # Full Postgres + PostGIS + RLS
├── .env.example
└── package.json
Auth (Supabase)
Auth is wired via src/lib/auth/context.tsx + AuthModal.tsx:
- Join Free in nav → email/password signup or login
- Continue Anonymously →
signInAnonymously()(enable in Supabase Dashboard → Auth → Providers → Anonymous) - Profile page syncs to
profilestable when signed in
Enable on https://supabase.onsethost.com → Authentication → Providers:
- Email (confirm email optional for dev)
- Anonymous sign-ins
Supabase Setup
1. Create project
Go to supabase.com → New Project (free tier).
2. Run schema
SQL Editor → paste contents of supabase/schema.sql → Run.
3. Enable Realtime
Dashboard → Database → Replication → enable chat_messages and profiles.
4. Create Storage bucket
INSERT INTO storage.buckets (id, name, public) VALUES ('gallery', 'gallery', true);
INSERT INTO storage.buckets (id, name, public) VALUES ('shop', 'shop', true);
5. Copy keys to .env.local
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
CLI alternative
npx supabase init
npx supabase link --project-ref YOUR_PROJECT_REF
npx supabase db push
5-Minute Deployment (Vercel + Supabase + DNS)
Step 1 — Push to GitHub (1 min)
git init
git add .
git commit -m "ExposedGays starter"
gh repo create exposedgays --private --push
Step 2 — Vercel deploy (2 min)
- vercel.com → Import Git repo
- Framework: Next.js (auto-detected)
- Add environment variables from
.env.example - Deploy → get
exposedgays.vercel.app
Step 3 — Custom domain (1 min)
- Vercel → Project → Settings → Domains → Add
exposedgays.com+www.exposedgays.com - Vercel shows required DNS records
Step 4 — DNS at registrar (1 min)
| Type | Name | Value |
|---|---|---|
| A | @ | 76.76.21.21 |
| CNAME | www | cname.vercel-dns.com |
(Or use Cloudflare CNAME flattening if proxied.)
Step 5 — Verify
- Visit
https://exposedgays.com— age gate appears - Map loads with cruiser icons
- Shop nav works with affiliate buttons
- PWA installable on mobile
Shop Affiliate Notes
- Cart is localStorage only — no checkout on-site
- "Buy Now" opens affiliate URLs in new tab (
rel="sponsored") - Replace placeholder URLs with real Amazon Associates / AdamMale affiliate links
- Products defined in
src/lib/products.ts(static) orshop_productstable (DB)
License
Private — exposedgays.com © 2026
Description
Languages
TypeScript
64.7%
Python
30%
PLpgSQL
3.8%
CSS
1.3%
Dockerfile
0.1%