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>
8.1 KiB
Local Development Setup
This guide will help you set up the CS2.WTF frontend for local development.
Prerequisites
- Node.js: v18.x or v20.x (check with
node --version) - npm: v9.x or higher (comes with Node.js)
- Backend API: Either local csgowtfd service OR access to production API
Quick Start
1. Install Dependencies
npm install
2. Environment Configuration
The .env file already exists in the project. You can use it as-is or modify it:
Option A: Use Production API (Recommended for frontend development)
# Use the live production API - no local backend needed
VITE_API_BASE_URL=https://api.csgow.tf
VITE_API_TIMEOUT=10000
VITE_DEBUG_MODE=true
VITE_ENABLE_ANALYTICS=false
Option B: Use Local Backend (For full-stack development)
# Use local backend (requires csgowtfd running on port 8000)
VITE_API_BASE_URL=http://localhost:8000
VITE_API_TIMEOUT=10000
VITE_DEBUG_MODE=true
VITE_ENABLE_ANALYTICS=false
3. Start the Development Server
npm run dev
The frontend will be available at http://localhost:5173
You should see output like:
[Vite Config] API Proxy target: https://api.csgow.tf
[API Client] Development mode - using Vite proxy
[API Client] Frontend requests: /api/*
[API Client] Proxy target: https://api.csgow.tf
➜ Local: http://localhost:5173/
4. (Optional) Start Local Backend
Only needed if using VITE_API_BASE_URL=http://localhost:8000:
# In the csgowtfd repository
cd ../csgowtfd
go run cmd/csgowtfd/main.go
Or use Docker:
docker-compose up csgowtfd
How the CORS Proxy Works
The Vite dev server includes a built-in proxy that eliminates CORS issues during development:
Development Mode Flow
1. Browser makes request to: http://localhost:5173/api/matches
2. Vite intercepts and proxies to: ${VITE_API_BASE_URL}/matches
3. Backend responds
4. Vite forwards response to browser
Benefits
- ✅ No CORS errors - All requests appear same-origin to the browser
- ✅ Works with any backend - Local or remote
- ✅ No backend CORS config needed - Proxy handles it
- ✅ Simple configuration - Just set
VITE_API_BASE_URL
Proxy Logs
You'll see detailed proxy activity in the terminal:
[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
Production vs Development
| Mode | API Base URL | CORS |
|---|---|---|
Development (npm run dev) |
/api (proxied to VITE_API_BASE_URL) |
✅ No issues |
Production (npm run build) |
VITE_API_BASE_URL (direct) |
✅ Backend has CORS enabled |
Troubleshooting
No Data Showing / Network Errors
Problem: Frontend loads but shows no matches, players show "Failed to load" errors.
Solutions:
-
Check what backend you're using:
# Look at your .env file cat .env | grep VITE_API_BASE_URL -
If using production API (
https://api.csgow.tf):# Test if production API is accessible curl https://api.csgow.tf/matches?limit=1Should return JSON data. If not, production API may be down.
-
If using local backend (
http://localhost:8000):# Test if local backend is running curl http://localhost:8000/matches?limit=1If you get "Connection refused", start the backend service.
-
Check proxy logs:
- Look at the terminal running
npm run dev - You should see
[Proxy]messages showing requests being forwarded - If you see
[Proxy Error], check the error message
- Look at the terminal running
-
Check browser console:
- Open DevTools → Console tab
- Look for
[API Client]messages showing proxy configuration - Network tab should show requests to
/api/*(not external URLs)
-
Restart dev server:
# Stop dev server (Ctrl+C) npm run dev
CORS Errors (Should Not Happen)
If you see CORS errors in the browser console, the proxy isn't working:
Symptoms:
- Browser console shows:
CORS policy: No 'Access-Control-Allow-Origin' header - Network tab shows requests going to
https://api.csgow.tfdirectly (not/api)
Fix:
- Verify you're in development mode (not production build)
- Check API client logs show:
Development mode - using Vite proxy - Restart dev server with clean cache:
rm -rf .svelte-kit npm run dev
Port Already in Use
If port 5173 is already in use:
# Vite will automatically try the next available port
npm run dev
# Or specify a custom port
npm run dev -- --port 3000
Backend Connection Issues
If the backend is on a different host/port, update .env:
# Custom backend location
VITE_API_BASE_URL=http://192.168.1.100:8080
Then restart the dev server.
Development Workflow
1. Make Changes
Edit files in src/. The dev server has hot module replacement (HMR):
- Component changes reload instantly
- Route changes reload the page
- Store changes reload affected components
2. Type Checking
Run TypeScript type checking:
npm run check # Check once
npm run check:watch # Watch mode
3. Linting
npm run lint # Check for issues
npm run lint:fix # Auto-fix issues
npm run format # Run Prettier
4. Testing
# Unit tests
npm run test # Run once
npm run test:watch # Watch mode
npm run test:coverage # Generate coverage report
# E2E tests
npm run test:e2e # Headless
npm run test:e2e:ui # Playwright UI
API Endpoints
The backend provides these endpoints (see docs/API.md for full details):
GET /matches- List all matchesGET /match/:id- Get match detailsGET /match/:id/rounds- Get round economy dataGET /match/:id/weapons- Get weapon statisticsGET /match/:id/chat- Get chat messagesGET /player/:id- Get player profile
How Requests Work
In Development (npm run dev):
Frontend code: api.matches.getMatches()
↓
API Client: GET /api/matches
↓
Vite Proxy: GET https://api.csgow.tf/matches
↓
Response: ← Data returned to frontend
In Production (deployed app):
Frontend code: api.matches.getMatches()
↓
API Client: GET https://api.csgow.tf/matches (direct)
↓
Response: ← Data returned to frontend
The API client automatically uses the correct URL based on environment.
Mock Data (Alternative: No Backend)
If you want to develop without any backend (local or production), enable MSW mocking:
-
Update
.env:VITE_ENABLE_MSW_MOCKING=true -
Restart dev server
The app will use mock data from src/mocks/handlers/.
Note: Mock data is limited and may not reflect all features. Production API is recommended for most development work.
Building for Production
# Build
npm run build
# Preview production build locally
npm run preview
The preview server runs on http://localhost:4173 and uses the production API configuration.
Environment Variables Reference
| Variable | Default | Description |
|---|---|---|
VITE_API_BASE_URL |
http://localhost:8000 |
Backend API base URL |
VITE_API_TIMEOUT |
10000 |
Request timeout (ms) |
VITE_ENABLE_LIVE_MATCHES |
false |
Enable live match polling |
VITE_ENABLE_ANALYTICS |
false |
Enable analytics tracking |
VITE_DEBUG_MODE |
false |
Enable debug logging |
VITE_ENABLE_MSW_MOCKING |
false |
Use mock data instead of API |
Getting Help
- Frontend Issues: Check browser console for errors
- API Issues: Check backend logs and proxy output in terminal
- Type Errors: Run
npm run checkfor detailed messages - Build Issues: Delete
.svelte-kit/andnode_modules/, thennpm install
Next Steps
- Read
TODO.mdfor current development status - Check
docs/DESIGN.mdfor design system documentation - Review
docs/API.mdfor complete API reference - See
README.mdfor project overview