Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Visigine
GEO/SEO-Auditor für AI-Suchen (ChatGPT, Claude, Perplexity, Gemini …). Frontend: React 19 + Vite. Backend: Node 20 + Express.
Dev-Setup
# Frontend deps
npm install
# Backend deps
npm install --prefix server
# Backend secrets
cp server/.env.example server/.env
# → MISTRAL_KEY=... in server/.env eintragen
Start
npm run dev
Startet client (Vite, Port 5173) und server (Express, Port 3001) parallel.
Vite proxied /api/* automatisch an den Backend-Port.
Health-Check: curl http://localhost:3001/health → {"ok":true}.
Secrets
Der Mistral-API-Key liegt nur in server/.env als MISTRAL_KEY.
Es gibt keine VITE_*-Keys im Frontend — der Browser sieht den Schlüssel nie.
Stack
- React 19, Vite 8 (kein TypeScript)
- Express 4, Node 20 native
fetch - Mistral
mistral-large-latest(nur serverseitig)
Production Deployment
Backend (server/)
Required env vars:
MISTRAL_KEY— Mistral API key (server-only, never exposed to the client).PORT— port to bind (default3001).ALLOWED_ORIGINS— comma-separated CORS whitelist (e.g.https://www.visigine.de,https://visigine.de).NODE_ENV=production— disables debug mode unconditionally.ALLOW_PRIVATE_HOSTS=0— keep at0in production (SSRF protection).
Run: npm start inside server/. The Express listener binds 0.0.0.0:$PORT
so containers and reverse proxies can reach it.
Health check: GET /health → { "ok": true }.
Frontend
Static build: npm run build in the repo root → dist/. Serve via any
static host. The frontend calls /api/analyze — your hosting layer must
proxy /api/* to the backend (nginx / Caddy / Cloudflare Workers / etc.).
Operations
- Rate limit: 20 requests / 60 s / IP on
/api/analyze. - In-memory cache: 1 h TTL, 1000 entries (LRU).
X-Cache: HIT|MISSheader. - Every request gets an
X-Request-Idand a structured log line. ?debug=1is ignored whenNODE_ENV=production.