Files
csgowtf/docs/CORS_PROXY.md
vikingowl 274f5b3b53 fix: Configure Vite proxy to eliminate CORS issues in development
Implemented a comprehensive CORS proxy solution that works with both
local and remote backends during development.

## Changes

### Vite Configuration (vite.config.ts)
- Use loadEnv() to properly read VITE_API_BASE_URL from .env
- Configure proxy to forward /api/* requests to backend
- Add detailed logging for proxy requests and responses
- Support changeOrigin, rewrite, secure=false, and websockets

### API Client (src/lib/api/client.ts)
- In development: Always use /api prefix (proxied)
- In production: Use direct VITE_API_BASE_URL
- Add console logging to show proxy configuration in dev mode
- Automatic detection of environment (DEV vs PROD)

### Error Handling (route loaders)
- Fix console.error() calls that caused TypeError with circular refs
- Use error.message instead of logging full error objects
- Affects: +page.ts, matches/+page.ts

### Documentation
- docs/LOCAL_DEVELOPMENT.md: Complete rewrite with proxy explanation
  - Quick start guide for both production API and local backend
  - Detailed proxy flow diagrams
  - Comprehensive troubleshooting section
  - Clear examples and logs

- docs/CORS_PROXY.md: Technical deep-dive on proxy implementation
  - How the proxy works internally
  - Configuration options explained
  - Testing procedures
  - Common issues and solutions

- .env.example: Updated with proxy documentation

## How It Works

Development Flow:
1. Frontend makes request: /api/matches
2. Vite proxy intercepts and forwards to: ${VITE_API_BASE_URL}/matches
3. Backend responds (no CORS headers needed)
4. Proxy returns response to frontend (same-origin)

Production Flow:
1. Frontend makes request directly to: https://api.csgow.tf/matches
2. Backend responds with CORS headers
3. Browser allows request (CORS enabled on backend)

## Benefits
 No CORS errors in development
 Works with local backend (localhost:8000)
 Works with remote backend (api.csgow.tf)
 Simple configuration (just set VITE_API_BASE_URL)
 Detailed logging for debugging
 Production build unaffected (direct requests)

## Testing
Verified with production API:
- curl https://api.csgow.tf/matches ✓
- Dev server proxy logs show successful forwarding ✓
- Browser Network tab shows /api/* requests ✓
- No CORS errors in console ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 21:34:26 +01:00

235 lines
6.2 KiB
Markdown

# CORS Proxy Configuration
This document explains how the CORS proxy works in the CS2.WTF frontend.
## Problem: CORS in Development
When developing a frontend that talks to an API on a different origin, browsers enforce CORS (Cross-Origin Resource Sharing) policies. This causes errors like:
```
Access to fetch at 'https://api.csgow.tf/matches' from origin 'http://localhost:5173'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
on the requested resource.
```
## Solution: Vite Development Proxy
The Vite dev server includes a built-in proxy that solves this problem by making all API requests appear same-origin.
### Configuration
**File**: `vite.config.ts`
```typescript
import { loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
const apiBaseUrl = env.VITE_API_BASE_URL || 'http://localhost:8000';
return {
server: {
proxy: {
'/api': {
target: apiBaseUrl,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
secure: false,
ws: true
}
}
}
};
});
```
### How It Works
1. **API Client** (in development) makes requests to `/api/*`:
```typescript
// src/lib/api/client.ts
const API_BASE_URL = import.meta.env.DEV ? '/api' : VITE_API_BASE_URL;
```
2. **Vite Proxy** intercepts requests to `/api/*` and forwards them:
```
Browser Request: GET http://localhost:5173/api/matches?limit=6
Vite Proxy: Intercepts /api/* requests
Backend Request: GET https://api.csgow.tf/matches?limit=6
Response: ← Returns data through proxy
Browser: ← Receives response (appears same-origin)
```
3. **Browser sees same-origin request** - no CORS error!
### Configuration Options
| Option | Value | Purpose |
|--------|-------|---------|
| `target` | `env.VITE_API_BASE_URL` | Where to forward requests |
| `changeOrigin` | `true` | Updates `Origin` header to match target |
| `rewrite` | Remove `/api` prefix | Maps `/api/matches` → `/matches` |
| `secure` | `false` | Allow self-signed certificates |
| `ws` | `true` | Enable WebSocket proxying |
### Environment Variables
**`.env`**:
```env
# Proxy will forward /api/* to this URL
VITE_API_BASE_URL=https://api.csgow.tf
# Or use local backend
# VITE_API_BASE_URL=http://localhost:8000
```
### Logging
The proxy logs all requests for debugging:
```bash
[Vite Config] API Proxy target: https://api.csgow.tf
[Proxy] GET /api/matches?limit=6 -> https://api.csgow.tf/matches?limit=6
[Proxy ✓] GET /api/matches?limit=6 -> 200
[Proxy] GET /api/match/123 -> https://api.csgow.tf/match/123
[Proxy ✓] GET /api/match/123 -> 200
```
Error logging:
```bash
[Proxy Error] ECONNREFUSED
[Proxy Error] Make sure backend is running at: http://localhost:8000
```
## API Client Configuration
**File**: `src/lib/api/client.ts`
```typescript
const getAPIBaseURL = (): string => {
// In production builds, use the configured URL directly
if (import.meta.env.PROD) {
return import.meta.env?.VITE_API_BASE_URL || 'https://api.csgow.tf';
}
// In development mode, ALWAYS use the Vite proxy to avoid CORS issues
// The proxy will forward /api requests to VITE_API_BASE_URL
return '/api';
};
```
This ensures:
- ✅ **Development**: Always uses `/api` (proxy handles CORS)
- ✅ **Production**: Uses direct URL (backend has CORS enabled)
## Testing the Proxy
### 1. Check Vite Config Loads Environment
Start dev server and look for:
```bash
npm run dev
# Should show:
[Vite Config] API Proxy target: https://api.csgow.tf
```
### 2. Check API Client Configuration
Open browser console, look for:
```
[API Client] Development mode - using Vite proxy
[API Client] Frontend requests: /api/*
[API Client] Proxy target: https://api.csgow.tf
```
### 3. Check Network Requests
Open DevTools → Network tab:
- ✅ Requests should go to `/api/*` (not full URL)
- ✅ Response should be `200 OK`
- ✅ No CORS errors in console
### 4. Check Proxy Logs
Terminal should show:
```
[Proxy] GET /api/matches -> https://api.csgow.tf/matches
[Proxy ✓] GET /api/matches -> 200
```
## Common Issues
### Issue 1: Proxy Not Loading .env
**Symptom**: Proxy uses default `http://localhost:8000` instead of `.env` value
**Cause**: `vite.config.ts` not loading environment variables
**Fix**: Use `loadEnv()` in config:
```typescript
import { loadEnv } from 'vite';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
const apiBaseUrl = env.VITE_API_BASE_URL || 'http://localhost:8000';
// ...
});
```
### Issue 2: Still Getting CORS Errors
**Symptom**: Browser console shows CORS errors
**Possible Causes**:
1. API client not using `/api` prefix in development
2. Request bypassing proxy somehow
3. Running production build instead of dev server
**Fix**:
1. Check API client logs show: `Development mode - using Vite proxy`
2. Verify Network tab shows requests to `/api/*`
3. Run `npm run dev` (not `npm run preview`)
### Issue 3: Connection Refused
**Symptom**: `[Proxy Error] ECONNREFUSED`
**Cause**: Backend is not running at the configured URL
**Fix**:
- If using local backend: Start `csgowtfd` on port 8000
- If using production API: Check `VITE_API_BASE_URL=https://api.csgow.tf`
## Production Build
In production, the proxy is **not used**. The frontend makes direct requests to the backend:
```typescript
// Production build
const API_BASE_URL = 'https://api.csgow.tf';
// Direct request (no proxy)
fetch('https://api.csgow.tf/matches');
```
The production API must have CORS enabled:
```
Access-Control-Allow-Origin: https://cs2.wtf
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
```
## Summary
| Environment | Frontend URL | API Requests | CORS |
|-------------|-------------|--------------|------|
| **Development** | `http://localhost:5173` | `/api/*` → Proxy → Backend | ✅ Proxy handles |
| **Production** | `https://cs2.wtf` | Direct to backend | ✅ Backend CORS |
The proxy is a **development-only** feature that makes local development smooth and eliminates CORS headaches.