Collegiate Deadlock esports site: schools map, current/past events, teams, Discord login, optional form notifications (Discord webhook), optional Turnstile on forms, and ingest APIs for the Discord bot.
Repository: github.com/g8tsz/deadlock-web
npm install
cp .env.example .env
npx prisma generate
npx prisma db push
npx prisma db seed- SQLite (default in
.env.example) stores data inprisma/dev.db(gitignored). Good for local development. - PostgreSQL is supported for production: set
DATABASE_URLto a Postgres connection string and runnpx prisma migrate deploy(see Vercel / production).
Create an app at the Discord Developer Portal β OAuth2 β Redirects: http://localhost:3000/api/auth/callback/discord (add your production URL when you deploy).
In .env set:
DISCORD_CLIENT_IDDISCORD_CLIENT_SECRETNEXTAUTH_SECRET(e.g.openssl rand -base64 32)
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SITE_URL |
Canonical public URL (sitemap, Open Graph). On Vercel, VERCEL_URL is a fallback if unset. |
NEXTAUTH_URL |
Must match the origin users hit (scheme + host, no trailing slash), e.g. https://your-domain.com. Vercel preview URLs each have a different host: add each preview URL to Discord OAuth redirects, or use production-only sign-in. |
FORMS_DISCORD_WEBHOOK_URL |
Discord webhook for contact + newsletter. Host must be discord.com or discordapp.com. Required in production for forms to succeed; local dev logs submissions instead. |
NEXT_PUBLIC_TURNSTILE_SITE_KEY + TURNSTILE_SECRET_KEY |
Optional Cloudflare Turnstile β set both to require a solved widget on forms. |
BOT_INGEST_ALLOWED_IPS |
Optional comma-separated IPs allowed to call ingest APIs after bearer auth (see docs/INGEST.md). |
npm run devOpen the URL Next.js prints (e.g. http://localhost:3000); if port 3000 is in use it may be 3001 or 3002. Many pages need the database: run db push and db seed first or you may see errors until SQLite exists and is seeded.
- Create a Postgres database (Vercel Postgres, Neon, Supabase, etc.) and set
DATABASE_URLin the project environment. - Build command: use
npm run vercel-buildwhenDATABASE_URLis Postgres (runsprisma migrate deploythen build). For SQLite-only preview branches, override the install command tonpm run build(or a branch env without Postgres) somigrate deploydoes not run against a missing DB. - Set
NEXTAUTH_URLandNEXT_PUBLIC_SITE_URLtohttps://your-domain, and add Discord OAuth redirecthttps://your-domain/api/auth/callback/discord. - Set
FORMS_DISCORD_WEBHOOK_URLfor live form delivery; add Turnstile keys if you want CAPTCHA on forms.
- Home: Upcoming matches, current standings, CTAs
- Events / schools / schedule: Data-driven from Prisma
- News: List at
/newsand articles at/news/[slug] - 404 / errors:
app/not-found.tsx,app/error.tsx,app/global-error.tsx - Privacy:
/privacy(linked in the footer) - Security headers: root
middleware.tssetsX-Content-Type-Options,Referrer-Policy,X-Frame-Options, and a minimalPermissions-Policy - Sign in with Discord: Optional when Discord app credentials are set
- Bot ingest API:
POST /api/ingest/matchand/api/ingest/standingsβ see docs/INGEST.md
- Local: SQLite at
prisma/dev.db. Editprisma/seed.tsand runnpx prisma db seedto refresh seed data. - Production: Prefer Postgres + migrations in
prisma/migrations/.
| Script | Purpose |
|---|---|
npm run dev |
Next.js dev server |
npm run build |
prisma generate + next build |
npm run lint |
ESLint |
npm run test:e2e |
Playwright smoke tests (requires npm run build then npm run start, or let Playwright start the server β see playwright.config.ts) |
npm run db:push |
Push schema (dev SQLite) |
npm run db:seed |
Run seed |
Articles are defined in lib/news-posts.ts. For a CMS or MDX later, replace that module with your content pipeline.
sharpis included sonext/imageoptimization works reliably in Node deployments (recommended by Next.js).- Run
npm auditperiodically. Some reported issues (e.g. ineslint-config-next/nextdev tooling) may only fix with major upgrades (npm audit fix --force); treat those as planned upgrades, not blind bumps.
MIT β see LICENSE.