mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-25 00:51:12 -05:00
307 lines
6.8 KiB
Markdown
307 lines
6.8 KiB
Markdown
# Environment Variables Guide
|
|
|
|
**For:** ThrillWiki Next.js 15 Migration
|
|
**Last Updated:** November 9, 2025
|
|
|
|
---
|
|
|
|
## 🎯 Overview
|
|
|
|
This guide covers all environment variables required for the ThrillWiki migration from React→Next.js 15 and Supabase→Django.
|
|
|
|
## 🔑 Critical Rules
|
|
|
|
1. **NO HARDCODED VALUES** - All configuration must use environment variables
|
|
2. **Client vs Server** - Understand NEXT_PUBLIC_ prefix usage
|
|
3. **Never commit secrets** - .env.local in .gitignore
|
|
4. **.env.example** - Document all required vars (without values)
|
|
5. **Validate on startup** - Fail fast if required vars missing
|
|
|
|
---
|
|
|
|
## 📋 Required Environment Variables
|
|
|
|
### Next.js Client-Side (Public)
|
|
|
|
These variables are exposed to the browser. Use `NEXT_PUBLIC_` prefix.
|
|
|
|
```bash
|
|
# Django API (required)
|
|
NEXT_PUBLIC_DJANGO_API_URL=https://api.thrillwiki.com
|
|
|
|
# CloudFlare Images (required for uploads)
|
|
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID=your_account_id_here
|
|
```
|
|
|
|
### Next.js Server-Side (Private)
|
|
|
|
These variables are ONLY available server-side. NO `NEXT_PUBLIC_` prefix.
|
|
|
|
```bash
|
|
# CloudFlare API Token (for image uploads from server)
|
|
CLOUDFLARE_API_TOKEN=your_secret_token_here
|
|
|
|
# Django Admin Credentials (if needed for server-side operations)
|
|
DJANGO_ADMIN_KEY=your_admin_key_here
|
|
```
|
|
|
|
### Legacy Supabase (Temporary - Remove in Phase 14)
|
|
|
|
Keep these ONLY during migration phases 1-13:
|
|
|
|
```bash
|
|
# Supabase (to be removed)
|
|
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key_here
|
|
```
|
|
|
|
---
|
|
|
|
## 📁 File Structure
|
|
|
|
```
|
|
project-root/
|
|
├── .env.local # Local development (git-ignored)
|
|
├── .env.example # Template (git-committed)
|
|
├── .env.production # Production (if needed, git-ignored)
|
|
└── .env.test # Testing (git-ignored)
|
|
```
|
|
|
|
### .env.local (Development)
|
|
|
|
```bash
|
|
# ================================
|
|
# Next.js Environment Variables
|
|
# ================================
|
|
|
|
# Django REST API
|
|
NEXT_PUBLIC_DJANGO_API_URL=http://localhost:8000/api/v1
|
|
|
|
# CloudFlare Images
|
|
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID=your_dev_account_id
|
|
CLOUDFLARE_API_TOKEN=your_dev_token
|
|
|
|
# Supabase (temporary - remove after Phase 14)
|
|
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
|
|
|
|
# Development flags
|
|
NODE_ENV=development
|
|
```
|
|
|
|
### .env.example (Template)
|
|
|
|
```bash
|
|
# ================================
|
|
# Next.js Environment Variables
|
|
# Copy to .env.local and fill in values
|
|
# ================================
|
|
|
|
# Django REST API (required)
|
|
NEXT_PUBLIC_DJANGO_API_URL=
|
|
|
|
# CloudFlare Images (required)
|
|
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID=
|
|
CLOUDFLARE_API_TOKEN=
|
|
|
|
# Supabase (temporary - will be removed)
|
|
NEXT_PUBLIC_SUPABASE_URL=
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=
|
|
```
|
|
|
|
### .env.production (Production)
|
|
|
|
```bash
|
|
# Django REST API
|
|
NEXT_PUBLIC_DJANGO_API_URL=https://api.thrillwiki.com
|
|
|
|
# CloudFlare Images
|
|
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID=production_account_id
|
|
CLOUDFLARE_API_TOKEN=production_secret_token
|
|
|
|
# Production settings
|
|
NODE_ENV=production
|
|
```
|
|
|
|
---
|
|
|
|
## 🔐 Security Best Practices
|
|
|
|
### 1. Client vs Server Variables
|
|
|
|
```typescript
|
|
// ❌ WRONG - Exposes secret to browser
|
|
const apiKey = process.env.CLOUDFLARE_API_TOKEN;
|
|
|
|
// ✅ CORRECT - Only available server-side
|
|
// In Server Component or API Route
|
|
const apiKey = process.env.CLOUDFLARE_API_TOKEN;
|
|
|
|
// ✅ CORRECT - Public variable in client
|
|
const apiUrl = process.env.NEXT_PUBLIC_DJANGO_API_URL;
|
|
```
|
|
|
|
### 2. Never Log Secrets
|
|
|
|
```typescript
|
|
// ❌ WRONG
|
|
console.log('API Token:', process.env.CLOUDFLARE_API_TOKEN);
|
|
|
|
// ✅ CORRECT
|
|
console.log('API URL:', process.env.NEXT_PUBLIC_DJANGO_API_URL);
|
|
```
|
|
|
|
### 3. Validate Environment Variables
|
|
|
|
```typescript
|
|
// lib/env.ts
|
|
import { z } from 'zod';
|
|
|
|
const envSchema = z.object({
|
|
NEXT_PUBLIC_DJANGO_API_URL: z.string().url(),
|
|
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID: z.string().min(1),
|
|
CLOUDFLARE_API_TOKEN: z.string().min(1).optional(), // Server-only
|
|
});
|
|
|
|
// Validate on app start
|
|
export const env = envSchema.parse({
|
|
NEXT_PUBLIC_DJANGO_API_URL: process.env.NEXT_PUBLIC_DJANGO_API_URL,
|
|
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID: process.env.NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID,
|
|
CLOUDFLARE_API_TOKEN: process.env.CLOUDFLARE_API_TOKEN,
|
|
});
|
|
|
|
// Usage
|
|
import { env } from '@/lib/env';
|
|
const apiUrl = env.NEXT_PUBLIC_DJANGO_API_URL;
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Deployment Environments
|
|
|
|
### Vercel
|
|
|
|
Set environment variables in Vercel dashboard:
|
|
|
|
1. Go to Project Settings → Environment Variables
|
|
2. Add each variable:
|
|
- `NEXT_PUBLIC_DJANGO_API_URL` = `https://api.thrillwiki.com`
|
|
- `NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID` = `your_account`
|
|
- `CLOUDFLARE_API_TOKEN` = `your_token` (mark as secret)
|
|
|
|
### Docker
|
|
|
|
Pass via docker-compose.yml:
|
|
|
|
```yaml
|
|
services:
|
|
nextjs:
|
|
environment:
|
|
- NEXT_PUBLIC_DJANGO_API_URL=https://api.thrillwiki.com
|
|
- NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID}
|
|
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
|
|
```
|
|
|
|
---
|
|
|
|
## 🧪 Testing
|
|
|
|
### Check Variables Are Loaded
|
|
|
|
```typescript
|
|
// Test in dev console (browser)
|
|
console.log('API URL:', process.env.NEXT_PUBLIC_DJANGO_API_URL);
|
|
// Should show the URL
|
|
|
|
console.log('Secret Token:', process.env.CLOUDFLARE_API_TOKEN);
|
|
// Should show 'undefined' (not exposed to client)
|
|
```
|
|
|
|
### Verify Build-Time Variables
|
|
|
|
```bash
|
|
# Build with verbose output
|
|
bun run build
|
|
|
|
# Check if variables are embedded
|
|
grep -r "NEXT_PUBLIC_DJANGO_API_URL" .next/
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Migration Phases
|
|
|
|
### Phase 1-13: Dual Variables
|
|
```bash
|
|
# Keep both during migration
|
|
NEXT_PUBLIC_DJANGO_API_URL=...
|
|
NEXT_PUBLIC_SUPABASE_URL=...
|
|
```
|
|
|
|
### Phase 14: Remove Supabase
|
|
```bash
|
|
# Remove these completely
|
|
# NEXT_PUBLIC_SUPABASE_URL=...
|
|
# NEXT_PUBLIC_SUPABASE_ANON_KEY=...
|
|
|
|
# Keep only Django
|
|
NEXT_PUBLIC_DJANGO_API_URL=...
|
|
```
|
|
|
|
---
|
|
|
|
## ⚠️ Common Issues
|
|
|
|
### Issue: Variable is undefined in browser
|
|
|
|
**Cause:** Missing `NEXT_PUBLIC_` prefix
|
|
|
|
**Fix:** Rename variable:
|
|
```bash
|
|
# Wrong
|
|
DJANGO_API_URL=https://api.thrillwiki.com
|
|
|
|
# Right
|
|
NEXT_PUBLIC_DJANGO_API_URL=https://api.thrillwiki.com
|
|
```
|
|
|
|
### Issue: Variable not updating after change
|
|
|
|
**Cause:** Next.js caches env vars at build time
|
|
|
|
**Fix:** Restart dev server:
|
|
```bash
|
|
# Stop server (Ctrl+C)
|
|
bun run dev
|
|
```
|
|
|
|
### Issue: Hardcoded URL slipped through
|
|
|
|
**Find:** Search codebase:
|
|
```bash
|
|
grep -r "https://api.thrillwiki.com" src/ --exclude-dir=node_modules
|
|
```
|
|
|
|
**Fix:** Replace with env var:
|
|
```typescript
|
|
// Before
|
|
const API_URL = "https://api.thrillwiki.com";
|
|
|
|
// After
|
|
const API_URL = process.env.NEXT_PUBLIC_DJANGO_API_URL;
|
|
```
|
|
|
|
---
|
|
|
|
## 🔗 Related Documentation
|
|
|
|
- [Phase 1: Foundation](./PHASE_01_FOUNDATION.md) - Initial setup
|
|
- [Phase 13: Next.js Optimization](./PHASE_13_NEXTJS_OPTIMIZATION.md) - Security
|
|
- [Bun Guide](./BUN_GUIDE.md) - Package manager
|
|
- Next.js Docs: https://nextjs.org/docs/app/building-your-application/configuring/environment-variables
|
|
|
|
---
|
|
|
|
**Document Version:** 1.0
|
|
**Last Updated:** November 9, 2025
|