11# MentoLoop Environment Variables Template
22# Copy this file to .env.local for development
3- # Use these variable names in Netlify Dashboard for production
3+ #
4+ # ============================================
5+ # PRODUCTION DEPLOYMENT NOTES
6+ # ============================================
7+ # β
= Required in Netlify production environment
8+ # βοΈ = Optional (has defaults, can be omitted)
9+ # π§ͺ = Development/Testing only (DO NOT set in production)
10+ # π¦ = Build-time only (set in Netlify Build scope, not runtime)
11+ #
12+ # See docs/NETLIFY_ENV_VARS.md for complete deployment guide
13+ #
14+ # AWS Lambda has 4KB env var limit. We've optimized by:
15+ # - Moving Stripe price IDs to lib/stripe/pricing-config.ts
16+ # - NEXT_PUBLIC_* vars are baked into build, not needed at runtime
17+ # - Removed test/dev variables from production
18+ #
19+ # Target: ~27 runtime variables in production
420
521# ============================================
6- # AUTHENTICATION (Clerk)
22+ # β
AUTHENTICATION (Clerk) - REQUIRED
723# ============================================
24+ CLERK_SECRET_KEY = sk_test_YOUR_CLERK_SECRET_KEY # β
Runtime required
25+ CLERK_JWT_ISSUER_DOMAIN = https://your-clerk-issuer.example.com # β
Runtime required
26+ CLERK_WEBHOOK_SECRET = whsec_YOUR_WEBHOOK_SECRET # β
Runtime required
27+
28+ # π¦ Build-time only (set in Netlify Build environment, not runtime)
829NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY = pk_test_YOUR_CLERK_PUBLISHABLE_KEY
9- CLERK_SECRET_KEY = sk_test_YOUR_CLERK_SECRET_KEY
10- CLERK_JWT_ISSUER_DOMAIN = https://your-clerk-issuer.example.com
11- CLERK_WEBHOOK_SECRET = whsec_YOUR_WEBHOOK_SECRET
1230
13- # Clerk URLs
31+ # π¦ Clerk URLs (baked into build)
1432NEXT_PUBLIC_CLERK_SIGN_IN_URL = /sign-in
1533NEXT_PUBLIC_CLERK_SIGN_UP_URL = /sign-up
1634NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL = /dashboard
@@ -19,126 +37,155 @@ NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/dashboard
1937NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL = /dashboard
2038
2139# ============================================
22- # DATABASE (Supabase)
40+ # β
DATABASE (Supabase) - REQUIRED
2341# ============================================
24- SUPABASE_URL = https://YOUR_SUPABASE_PROJECT.supabase.co
25- SUPABASE_SERVICE_ROLE_KEY = YOUR_SUPABASE_SERVICE_ROLE_KEY
26- SUPABASE_ANON_KEY = YOUR_SUPABASE_ANON_KEY
42+ SUPABASE_URL = https://YOUR_SUPABASE_PROJECT.supabase.co # β
Runtime required
43+ SUPABASE_SERVICE_ROLE_KEY = YOUR_SUPABASE_SERVICE_ROLE_KEY # β
Runtime required
44+ SUPABASE_ANON_KEY = YOUR_SUPABASE_ANON_KEY # β
Runtime required
45+
46+ # π¦ Build-time only (baked into client bundle)
2747NEXT_PUBLIC_SUPABASE_URL = https://YOUR_SUPABASE_PROJECT.supabase.co
2848NEXT_PUBLIC_SUPABASE_ANON_KEY = YOUR_SUPABASE_ANON_KEY
49+
50+ # βοΈ Optional (defaults provided)
2951SUPABASE_POOL_SIZE = 10
3052SUPABASE_SCHEMA = public
3153
3254# ============================================
33- # AI SERVICES
55+ # βοΈ AI SERVICES - OPTIONAL
3456# ============================================
35- OPENAI_API_KEY = sk-proj-YOUR_OPENAI_API_KEY
36- GEMINI_API_KEY = YOUR_GEMINI_API_KEY
57+ OPENAI_API_KEY = sk-proj-YOUR_OPENAI_API_KEY # βοΈ Optional - for AI matching
58+ GEMINI_API_KEY = YOUR_GEMINI_API_KEY # βοΈ Optional - for AI matching
3759
3860# ============================================
39- # PAYMENT PROCESSING (Stripe)
40- # SECURITY: Price IDs are SERVER-SIDE ONLY
41- # NEVER expose as NEXT_PUBLIC_* variables
61+ # β
PAYMENT PROCESSING (Stripe) - REQUIRED
4262# ============================================
63+ # SECURITY: Price IDs are SERVER-SIDE ONLY via lib/stripe/pricing-config.ts
64+ # NEVER expose as NEXT_PUBLIC_* variables
65+
66+ STRIPE_SECRET_KEY = sk_test_YOUR_STRIPE_SECRET_KEY # β
Runtime required
67+ STRIPE_WEBHOOK_SECRET = whsec_YOUR_STRIPE_WEBHOOK_SECRET # β
Runtime required
68+
69+ # π¦ Build-time only (baked into client bundle)
4370NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY = pk_test_YOUR_STRIPE_PUBLISHABLE_KEY
44- STRIPE_SECRET_KEY = sk_test_YOUR_STRIPE_SECRET_KEY
45- STRIPE_WEBHOOK_SECRET = whsec_YOUR_STRIPE_WEBHOOK_SECRET
46-
47- # Server-side Price IDs (NEVER prefix with NEXT_PUBLIC_)
48- STRIPE_PRICE_ID_STARTER = price_starter_example
49- STRIPE_PRICE_ID_CORE = price_core_example
50- STRIPE_PRICE_ID_ADVANCED = price_advanced_example
51- STRIPE_PRICE_ID_PRO = price_pro_example
52- STRIPE_PRICE_ID_ELITE = price_elite_example
53- STRIPE_PRICE_ID_PREMIUM = price_premium_example
54- STRIPE_PRICE_ID_ALACARTE = price_alacarte_example
55- STRIPE_PRICE_ID_ONECENT = price_penny_example
56- STRIPE_PRICE_ID_PENNY = price_penny_example
71+
72+ # β
Server-side Price IDs (accessed via lib/stripe/pricing-config.ts)
73+ STRIPE_PRICE_ID_STARTER = price_starter_example # β
Required
74+ STRIPE_PRICE_ID_CORE = price_core_example # β
Required
75+ STRIPE_PRICE_ID_ADVANCED = price_advanced_example # β
Required
76+ STRIPE_PRICE_ID_PRO = price_pro_example # β
Required
77+ STRIPE_PRICE_ID_ELITE = price_elite_example # β
Required
78+ STRIPE_PRICE_ID_PREMIUM = price_premium_example # β
Required
79+ STRIPE_PRICE_ID_ALACARTE = price_alacarte_example # β
Required
80+ STRIPE_PRICE_ID_ONECENT = price_penny_example # β
Required (discount code)
81+ STRIPE_PRICE_ID_PENNY = price_penny_example # β
Required (discount code)
5782
5883# Preceptor payout configuration
5984PRECEPTOR_PAYOUT_PERCENT = 0.70
6085
6186# ============================================
62- # COMMUNICATIONS
87+ # β
COMMUNICATIONS - REQUIRED
6388# ============================================
6489# Twilio (SMS)
65- TWILIO_ACCOUNT_SID = YOUR_TWILIO_ACCOUNT_SID
66- TWILIO_AUTH_TOKEN = YOUR_TWILIO_AUTH_TOKEN
67- TWILIO_PHONE_NUMBER = +1YOUR_PHONE_NUMBER
90+ TWILIO_ACCOUNT_SID = YOUR_TWILIO_ACCOUNT_SID # β
Runtime required
91+ TWILIO_AUTH_TOKEN = YOUR_TWILIO_AUTH_TOKEN # β
Runtime required
92+ TWILIO_PHONE_NUMBER = +1YOUR_PHONE_NUMBER # β
Runtime required
6893
6994# SendGrid (Email)
70- SENDGRID_API_KEY = SG.YOUR_SENDGRID_API_KEY
71- SENDGRID_FROM_EMAIL = support@mentoloop.com
72- EMAIL_DOMAIN = mentoloop.com
95+ SENDGRID_API_KEY = SG.YOUR_SENDGRID_API_KEY # β
Runtime required
96+ SENDGRID_FROM_EMAIL = support@mentoloop.com # β
Runtime required
97+ EMAIL_DOMAIN = mentoloop.com # βοΈ Optional (defaults to mentoloop.com)
7398
7499# ============================================
75- # APPLICATION SETTINGS
100+ # β
APPLICATION SETTINGS
76101# ============================================
77- NODE_ENV = production
102+ NODE_ENV = production # β
Runtime required (set to 'production' in Netlify)
103+
104+ # π¦ Build-time only (baked into client bundle)
78105NEXT_PUBLIC_APP_URL = https://YOUR_DOMAIN.com
79106NEXT_PUBLIC_API_URL = https://YOUR_DOMAIN.com/api
80107NEXT_PUBLIC_EMAIL_DOMAIN = mentoloop.com
81108NEXT_PUBLIC_ANALYTICS_ENDPOINT = https://YOUR_DOMAIN.com/api/analytics
82109NEXT_PUBLIC_DATA_LAYER = supabase
83110
84111# ============================================
85- # SECURITY SETTINGS
112+ # β
SECURITY SETTINGS
86113# ============================================
87- # CSRF Protection - Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
88- CSRF_SECRET_KEY = YOUR_64_CHARACTER_HEX_STRING_HERE
114+ # CSRF Protection - Generate with: openssl rand -base64 32
115+ CSRF_SECRET_KEY = YOUR_64_CHARACTER_HEX_STRING_HERE # β
Runtime required (min 32 chars)
89116
90- # Rate Limiting (Upstash Redis)
117+ # βοΈ Rate Limiting (Upstash Redis) - Optional, falls back to in-memory
91118# Get credentials from: https://console.upstash.com/
92- UPSTASH_REDIS_REST_URL = https://YOUR_UPSTASH_ENDPOINT.upstash.io
93- UPSTASH_REDIS_REST_TOKEN = YOUR_UPSTASH_REST_TOKEN
119+ UPSTASH_REDIS_REST_URL = https://YOUR_UPSTASH_ENDPOINT.upstash.io # βοΈ Optional
120+ UPSTASH_REDIS_REST_TOKEN = YOUR_UPSTASH_REST_TOKEN # βοΈ Optional
94121
95- # Other Security Settings ( Optional)
96- ADMIN_SECRET = admin-secret-key
97- ENABLE_SECURITY_HEADERS = true
122+ # βοΈ Other Security Settings - Optional (defaults provided )
123+ ADMIN_SECRET = admin-secret-key # βοΈ Optional
124+ ENABLE_SECURITY_HEADERS = true # βοΈ Optional (defaults to true)
98125
99126# ============================================
100- # FEATURE FLAGS (Optional )
127+ # βοΈ FEATURE FLAGS - OPTIONAL (all default to true )
101128# ============================================
102- ENABLE_AI_MATCHING = true
103- ENABLE_SMS_NOTIFICATIONS = true
104- ENABLE_EMAIL_NOTIFICATIONS = true
105- ENABLE_PAYMENT_PROCESSING = true
129+ # Only set these to 'false' to disable features
130+ ENABLE_AI_MATCHING = true # βοΈ Optional (defaults to true)
131+ ENABLE_SMS_NOTIFICATIONS = true # βοΈ Optional (defaults to true)
132+ ENABLE_EMAIL_NOTIFICATIONS = true # βοΈ Optional (defaults to true)
133+ ENABLE_PAYMENT_PROCESSING = true # βοΈ Optional (defaults to true)
106134
107135# ============================================
108- # MONITORING (Optional)
136+ # βοΈ MONITORING - OPTIONAL
109137# ============================================
110- SENTRY_DSN = YOUR_SENTRY_DSN
111- NEXT_PUBLIC_SENTRY_DSN = YOUR_SENTRY_PUBLIC_DSN
112- GOOGLE_ANALYTICS_ID = YOUR_GA_ID
113- CI = false
138+ SENTRY_DSN = YOUR_SENTRY_DSN # β
Recommended for production (error tracking)
139+ GOOGLE_ANALYTICS_ID = YOUR_GA_ID # βοΈ Optional
140+
141+ # π¦ Build-time only
142+ NEXT_PUBLIC_SENTRY_DSN = YOUR_SENTRY_PUBLIC_DSN # π¦ Optional (exposed to client)
114143
115- # Optional Social URLs (shown in footer if set)
116- NEXT_PUBLIC_TWITTER_URL =
117- NEXT_PUBLIC_LINKEDIN_URL =
118- NEXT_PUBLIC_FACEBOOK_URL =
119- NEXT_PUBLIC_TIKTOK_URL =
120- NEXT_PUBLIC_THREADS_URL =
144+ # βοΈ Social Media URLs (shown in footer if set, accessed via SOCIAL_URLS constant)
145+ NEXT_PUBLIC_TWITTER_URL = # βοΈ Optional (empty = not shown)
146+ NEXT_PUBLIC_LINKEDIN_URL = # βοΈ Optional (empty = not shown)
147+ NEXT_PUBLIC_FACEBOOK_URL = # βοΈ Optional (empty = not shown)
148+ NEXT_PUBLIC_TIKTOK_URL = # βοΈ Optional (empty = not shown)
149+ NEXT_PUBLIC_THREADS_URL = # βοΈ Optional (empty = not shown)
150+ NEXT_PUBLIC_INSTAGRAM_URL = # βοΈ Optional (empty = not shown)
121151
122152# ============================================
123- # TESTING (Development /CI only )
153+ # π§ͺ TESTING - DEVELOPMENT /CI ONLY (DO NOT SET IN PRODUCTION )
124154# ============================================
125- NEXT_RUNTIME = nodejs
126- CLERK_TEST_MODE = false
127- E2E_TEST = false
128- TEST_ADMIN_EMAIL = admin@example.com
129- TEST_ADMIN_PASSWORD = changeme
130- TEST_PRECEPTOR_EMAIL = preceptor@example.com
131- TEST_PRECEPTOR_PASSWORD = changeme
132- TEST_STUDENT_EMAIL = student@example.com
133- TEST_STUDENT_PASSWORD = changeme
134- TEST_PASSWORD = changeme
155+ NEXT_RUNTIME = nodejs # π§ͺ Dev only
156+ CLERK_TEST_MODE = false # π§ͺ Dev only
157+ E2E_TEST = false # π§ͺ Dev only
158+ TEST_ADMIN_EMAIL = admin@example.com # π§ͺ Dev only
159+ TEST_ADMIN_PASSWORD = changeme # π§ͺ Dev only
160+ TEST_PRECEPTOR_EMAIL = preceptor@example.com # π§ͺ Dev only
161+ TEST_PRECEPTOR_PASSWORD = changeme # π§ͺ Dev only
162+ TEST_STUDENT_EMAIL = student@example.com # π§ͺ Dev only
163+ TEST_STUDENT_PASSWORD = changeme # π§ͺ Dev only
164+ TEST_PASSWORD = changeme # π§ͺ Dev only
165+
166+ # π§ͺ CI Variables (DO NOT SET IN PRODUCTION)
167+ CI = false # π§ͺ CI only
168+ BUILD_TIMEOUT = 600 # π§ͺ CI only
169+ CACHE_MAX_AGE = 3600 # π§ͺ CI only
170+ NODE_OPTIONS = --max-old-space-size=4096 # π§ͺ Build only
171+ SECRETS_SCAN_ENABLED = false # π§ͺ CI only
135172
136173# ============================================
137- # SECURITY NOTES FOR DEPLOYMENT
174+ # π PRODUCTION DEPLOYMENT CHECKLIST
138175# ============================================
176+ # β
Set ~27 runtime variables in Netlify (see docs/NETLIFY_ENV_VARS.md)
177+ # β
Remove all NEXT_PUBLIC_* from production runtime (keep in build scope)
178+ # β
Remove all TEST_*, CI, BUILD_* variables from production
179+ # β
Use production keys (pk_live_, sk_live_) for live deployment
180+ # β
Generate strong CSRF_SECRET_KEY: openssl rand -base64 32
181+ # β
Verify all 9 Stripe price IDs are set correctly
182+ # β
Test deployment: npm run validate:env-size
183+ #
184+ # SECURITY NOTES:
139185# 1. NEVER expose Price IDs as NEXT_PUBLIC_* variables
140- # 2. Price IDs are handled server-side via /api/create-checkout
186+ # 2. Price IDs accessed server-side via lib/stripe/pricing-config.ts
141187# 3. All Stripe operations use server-side validation
142- # 4. Use production keys for live deployment (pk_live_, sk_live_)
143- # 5. Use test keys for staging/development (pk_test_, sk_test_)
144- # 6. Never commit actual API keys to your repository
188+ # 4. NEXT_PUBLIC_* vars are PUBLIC - visible in browser
189+ # 5. Never commit actual API keys to your repository
190+ #
191+ # See docs/NETLIFY_ENV_VARS.md for complete deployment guide
0 commit comments