Modern public profil platformu.
- Next.js 15 App Router
- TypeScript strict mode
- Tailwind CSS v4
- shadcn/ui tarzı yeniden kullanılabilir UI bileşenleri
- Supabase Auth ve PostgreSQL
- Cloudflare R2 medya depolama
- Vercel deployment
src/app
(auth)/login
(auth)/register
dashboard
[username]
src/components
dashboard
profile
ui
src/lib
r2.ts
supabase
themes.ts
validation.ts
utils.ts
src/types
supabase/schema.sqlnpm install
cp .env.example .env.local
npm run dev.env.local değerleri:
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
CLOUDFLARE_R2_ACCOUNT_ID=your-account-id
CLOUDFLARE_R2_ACCESS_KEY_ID=your-access-key-id
CLOUDFLARE_R2_SECRET_ACCESS_KEY=your-secret-access-key
CLOUDFLARE_R2_BUCKET=ghxsty-media
CLOUDFLARE_R2_PUBLIC_URL=https://cdn.ghxsty.lol
CRON_SECRET=change-this-long-random-secret
GIPHY_API_KEY=your-giphy-api-key
NEXT_PUBLIC_TURNSTILE_SITE_KEY=your-turnstile-site-key
TURNSTILE_SECRET_KEY=your-turnstile-secret-key
DISCORD_CLIENT_ID=your-discord-client-id
DISCORD_CLIENT_SECRET=your-discord-client-secret
DISCORD_REDIRECT_URI=http://localhost:3000/api/discord/callback- Supabase projesi oluştur.
supabase/schema.sqldosyasını SQL Editor içinde çalıştır.- Authentication > Providers altında Email provider açık olmalı.
- Discord ile giriş için Authentication > Providers > Discord açık olmalı.
- Discord Developer Portal > OAuth2 > Redirects içine Supabase callback URL eklenmeli:
https://PROJECT_REF.supabase.co/auth/v1/callback
- Supabase Auth > URL Configuration içinde app callback URL değerleri eklenmeli:
http://localhost:3000/auth/callbackhttps://ghxsty.lol/auth/callback
Şifreler uygulama veritabanında tutulmaz. Kimlik doğrulama tamamen Supabase Auth üzerinden yapılır.
- Cloudflare Dashboard içinde R2 bucket oluştur:
ghxsty-media. - R2 > Manage R2 API Tokens içinden Object Read & Write yetkili token oluştur.
- Account ID, Access Key ID ve Secret Access Key değerlerini
.env.localiçine ekle. - Bucket için public/custom domain ayarla. Önerilen:
cdn.ghxsty.lol. CLOUDFLARE_R2_PUBLIC_URLdeğerini bu public domain olarak gir.- R2 bucket CORS policy içine upload için şu izinleri ekle:
[
{
"AllowedOrigins": [
"http://localhost:3000",
"https://ghxsty.lol",
"https://www.ghxsty.lol"
],
"AllowedMethods": ["GET", "PUT", "HEAD"],
"AllowedHeaders": ["Content-Type"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]Avatar, arka plan ve müzik dosyaları R2 üzerinde tutulur. Supabase içinde yalnızca bu dosyaların public URL kayıtları saklanır.
Watch Party için Supabase SQL Editor içinde supabase/migrations/watch_party_schema.sql dosyasını çalıştır.
- Admin/moderatör paneli:
/dashboard/events - Public liste:
/events - Public etkinlik sayfası:
/events/[eventId] - Video upload R2 presigned URL ile yapılır; R2 secret client tarafına çıkmaz.
- Chat içindeki GIF araması GIPHY API ile yapılır. Bunun için
GIPHY_API_KEYgerekir. - Temizlik endpoint’i:
/api/events/cleanup
Vercel Cron kullanacaksan /api/events/cleanup endpoint’ine Authorization: Bearer CRON_SECRET header’ı gönderilecek şekilde ayarla. Bu endpoint süresi geçmiş ended event videolarını R2’den siler ve event’i deleted durumuna alır.
Kayıt formu Cloudflare Turnstile ile korunabilir.
- Cloudflare Dashboard > Turnstile içinden widget oluştur.
- Hostname olarak production domainini ve localhost geliştirme adresini ekle.
- Site key değerini
NEXT_PUBLIC_TURNSTILE_SITE_KEYiçine ekle. - Secret key değerini
TURNSTILE_SECRET_KEYiçine ekle.
TURNSTILE_SECRET_KEY tanımlıysa kayıt formunda gelen Turnstile token sunucuda doğrulanır.
Dashboard içinden Discord hesabı bağlanabilir.
- Discord Developer Portal içinde application oluştur.
- OAuth2 redirect URL olarak local ve production callback adreslerini ekle:
http://localhost:3000/api/discord/callbackhttps://ghxsty.lol/api/discord/callback
.env.localiçineDISCORD_CLIENT_ID,DISCORD_CLIENT_SECRETveDISCORD_REDIRECT_URIekle.- Production için Vercel Environment Variables alanına aynı değerleri gir.
- Supabase SQL Editor içinde
supabase/discord-integration.sqldosyasını çalıştır.
Canlı Discord etkinliği için public profilde Lanyard API kullanılır. Lanyard veri dönmezse yalnızca bağlı Discord profil bilgisi gösterilir.
- Repo’yu Vercel’e bağla.
- Environment Variables alanına şunları ekle:
NEXT_PUBLIC_SITE_URL=https://siteadi.comNEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYCLOUDFLARE_R2_ACCOUNT_IDCLOUDFLARE_R2_ACCESS_KEY_IDCLOUDFLARE_R2_SECRET_ACCESS_KEYCLOUDFLARE_R2_BUCKETCLOUDFLARE_R2_PUBLIC_URLCRON_SECRETGIPHY_API_KEYNEXT_PUBLIC_TURNSTILE_SITE_KEYTURNSTILE_SECRET_KEYDISCORD_CLIENT_IDDISCORD_CLIENT_SECRETDISCORD_REDIRECT_URI
- Supabase Auth > URL Configuration içinde Site URL ve Redirect URLs değerlerine production domainini ekle.
- Deploy et.
npm run dev
npm run lint
npm run build