Skip to main content

Overview

Sistema Financiero uses environment variables to store sensitive configuration like API keys and database URLs. This keeps secrets out of your code and allows different configurations for development and production.
Never commit .env.local to version control! The .gitignore file is configured to exclude it, but always double-check.

Environment File Setup

1

Copy Example File

Create your environment file from the template:
Terminal
cp .env.example .env.local
.env.local is automatically loaded by Next.js and takes precedence over .env.
2

Edit Environment Variables

Open .env.local in your code editor and fill in the values:
.env.local
# Supabase Configuration (REQUIRED)
NEXT_PUBLIC_SUPABASE_URL=your-supabase-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key

# OpenRouter API (OPTIONAL - for AI chat features)
# Get your key at: https://openrouter.ai/keys
OPENROUTER_API_KEY=

# App Configuration
NEXT_PUBLIC_APP_URL=http://localhost:3000
3

Restart Development Server

After modifying environment variables, restart your dev server:
Terminal
# Stop the server (Ctrl+C)
# Then restart:
npm run dev
Next.js only reads environment variables at startup. Changes require a restart.

Required Variables

These environment variables are mandatory for the application to function:

NEXT_PUBLIC_SUPABASE_URL

Description: Your Supabase project URL Where to find it:
  1. Go to your Supabase Dashboard
  2. Select your project
  3. Go to SettingsAPI
  4. Copy the Project URL
Format:
NEXT_PUBLIC_SUPABASE_URL=https://abcdefghijklmnop.supabase.co
The NEXT_PUBLIC_ prefix makes this variable available in browser code. This is safe because the URL is public.
Example:
NEXT_PUBLIC_SUPABASE_URL=https://xyzcompany.supabase.co

NEXT_PUBLIC_SUPABASE_ANON_KEY

Description: Your Supabase anonymous (public) API key Where to find it:
  1. Go to your Supabase Dashboard
  2. Select your project
  3. Go to SettingsAPI
  4. Copy the anon public key (not the service_role key!)
Format:
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Use the anon key, not the service_role key. The service_role key bypasses Row Level Security and should never be exposed in frontend code.
Example:
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh5emNvbXBhbnkiLCJyb2xlIjoiYW5vbiIsImlhdCI6MTY5MDAwMDAwMCwiZXhwIjoxNzIwMDAwMDAwfQ.abc123def456ghi789jkl012mno345pqr678stu901vwx234yz

NEXT_PUBLIC_APP_URL

Description: The base URL where your app is deployed Development:
NEXT_PUBLIC_APP_URL=http://localhost:3000
Production:
NEXT_PUBLIC_APP_URL=https://your-app.vercel.app
This is used for OpenRouter API attribution and generating absolute URLs (e.g., for receipts).

Optional Variables

These variables enable additional features:

OPENROUTER_API_KEY

Description: API key for AI-powered chat features Required for:
  • AI chat agent (/agente-mejorado page)
  • OCR receipt scanning (/upload-image API)
  • Natural language transaction entry
Where to get it:
  1. Go to OpenRouter.ai
  2. Sign up for a free account
  3. Go to Keys page
  4. Click Create Key
  5. Copy the key (starts with sk-or-v1-)
Format:
OPENROUTER_API_KEY=sk-or-v1-0123456789abcdef0123456789abcdef0123456789abcdef
This variable does NOT have the NEXT_PUBLIC_ prefix - it’s server-side only for security.
Pricing:
  • OpenRouter offers a free tier with $0.05 initial credit
  • Most models cost 0.0010.001-0.01 per request
  • Sistema Financiero uses google/gemini-2.5-flash (very affordable)
Example:
OPENROUTER_API_KEY=sk-or-v1-abc123def456ghi789jkl012mno345pqr678stu901vwx234yz567890
If you skip this variable, the AI chat and OCR features will not work. The rest of the app (manual entry, dashboard) will function normally.

Environment Variable Precedence

Next.js loads environment files in this order (later files override earlier):
  1. .env - Default values for all environments
  2. .env.local - Local overrides (git-ignored)
  3. .env.development - Development-specific
  4. .env.development.local - Local dev overrides
  5. .env.production - Production-specific
  6. .env.production.local - Local prod overrides
For most projects, using just .env.local is sufficient. It overrides everything.

Accessing Variables in Code

Client-Side (Browser)

Variables with NEXT_PUBLIC_ prefix:
components/Example.tsx
'use client'

export function Example() {
  // ✅ Accessible in browser
  const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
  
  // ❌ Returns undefined (no NEXT_PUBLIC_ prefix)
  const apiKey = process.env.OPENROUTER_API_KEY
  
  return <div>Supabase URL: {supabaseUrl}</div>
}

Server-Side (API Routes / Server Components)

All variables are accessible:
app/api/example/route.ts
import { NextResponse } from 'next/server'

export async function GET() {
  // ✅ Both accessible on server
  const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
  const openrouterKey = process.env.OPENROUTER_API_KEY
  
  return NextResponse.json({ 
    supabaseUrl,
    hasOpenRouterKey: !!openrouterKey // Don't expose the actual key!
  })
}
Never send server-only variables (without NEXT_PUBLIC_) to the client. They contain sensitive credentials.

Production Deployment

Vercel

Add environment variables in the Vercel dashboard:
1

Go to Project Settings

  1. Open your project in Vercel Dashboard
  2. Click Settings
  3. Click Environment Variables
2

Add Variables

For each variable:
  1. Key: Variable name (e.g., NEXT_PUBLIC_SUPABASE_URL)
  2. Value: Variable value
  3. Environment: Select Production, Preview, and Development
  4. Click Save
Checking all three environments ensures variables work in preview deployments and local development with Vercel CLI.
3

Redeploy

Trigger a new deployment:
Terminal
git commit --allow-empty -m "Update env vars"
git push
Or click Redeploy in the Vercel dashboard.

Railway

Add variables in the Railway dashboard:
1

Open Service Settings

  1. Go to Railway Dashboard
  2. Select your project
  3. Click on your service
  4. Go to Variables tab
2

Add Variables

Click New Variable and add each variable:
  • NEXT_PUBLIC_SUPABASE_URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY
  • OPENROUTER_API_KEY
  • NEXT_PUBLIC_APP_URL (use your Railway URL, e.g., https://your-app.up.railway.app)
3

Deploy

Railway automatically redeploys when you save variables.

Other Platforms

  1. Go to Site settingsBuild & deployEnvironment
  2. Click Edit variables
  3. Add each variable
  4. Redeploy your site
  1. Go to your service dashboard
  2. Click Environment tab
  3. Add each variable
  4. Click Save Changes
  5. Manually trigger a deploy from the Manual Deploy dropdown
Pass variables using -e flag:
docker run \
  -e NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co \
  -e NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGc... \
  -e OPENROUTER_API_KEY=sk-or-v1-... \
  -e NEXT_PUBLIC_APP_URL=https://your-domain.com \
  -p 3000:3000 \
  your-image-name
Or use a .env file:
docker run --env-file .env.production -p 3000:3000 your-image-name

Security Best Practices

Never Commit Secrets

  • Add .env.local to .gitignore
  • Use .env.example for documentation
  • Rotate keys if accidentally committed

Use NEXT_PUBLIC_ Carefully

  • Only for non-sensitive data
  • Exposed to all website visitors
  • Examples: Supabase URL, app version

Rotate Keys Regularly

  • Change API keys every 90 days
  • Use Supabase’s key rotation feature
  • Update all deployment environments

Different Keys per Environment

  • Use separate Supabase projects for dev/prod
  • Different OpenRouter keys for testing
  • Prevents accidental data mixing

Validating Your Setup

Check Environment Variables

Create a test API route to verify variables are loaded:
app/api/test-env/route.ts
import { NextResponse } from 'next/server'

export async function GET() {
  return NextResponse.json({
    hasSupabaseUrl: !!process.env.NEXT_PUBLIC_SUPABASE_URL,
    hasSupabaseKey: !!process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
    hasOpenRouterKey: !!process.env.OPENROUTER_API_KEY,
    appUrl: process.env.NEXT_PUBLIC_APP_URL,
  })
}
Visit http://localhost:3000/api/test-env to see:
Response
{
  "hasSupabaseUrl": true,
  "hasSupabaseKey": true,
  "hasOpenRouterKey": true,
  "appUrl": "http://localhost:3000"
}
Delete this test route before deploying to production! It exposes which secrets you have configured.

Test Supabase Connection

app/api/test-supabase/route.ts
import { NextResponse } from 'next/server'
import { supabase } from '@/lib/supabase'

export async function GET() {
  try {
    const { data, error } = await supabase
      .from('transacciones')
      .select('count')
      .limit(1)
    
    if (error) throw error
    
    return NextResponse.json({ 
      success: true, 
      message: 'Supabase connected successfully!' 
    })
  } catch (error) {
    return NextResponse.json({ 
      success: false, 
      error: String(error) 
    }, { status: 500 })
  }
}

Troubleshooting

Problem: App crashes with “Missing Supabase environment variables”Solution:
  1. Verify .env.local exists and is in the project root
  2. Check variable names match exactly (case-sensitive)
  3. Restart dev server after adding variables
  4. Ensure no extra spaces around = sign:
    # ✅ Correct
    NEXT_PUBLIC_SUPABASE_URL=https://example.supabase.co
    
    # ❌ Wrong (spaces)
    NEXT_PUBLIC_SUPABASE_URL = https://example.supabase.co
    
Problem: Variable shows undefined in codeSolution:
  1. Client-side: Add NEXT_PUBLIC_ prefix
  2. Server-side: Restart dev server (Next.js caches env vars)
  3. Check for typos in variable name
  4. Verify .env.local is in project root (not src/ or app/)
Problem: App works on localhost but fails on Vercel/RailwaySolution:
  1. Add variables to deployment platform’s UI (not just .env.local)
  2. Check you added them to “Production” environment
  3. Trigger a new deployment after saving variables
  4. Check deployment logs for specific error messages
Problem: AI chat doesn’t work, 401/403 errorsSolution:
  1. Verify OPENROUTER_API_KEY is set (no NEXT_PUBLIC_ prefix)
  2. Check you have credits at OpenRouter dashboard
  3. Ensure key starts with sk-or-v1-
  4. Test with curl:
    curl https://openrouter.ai/api/v1/auth/key \
      -H "Authorization: Bearer $OPENROUTER_API_KEY"
    

Next Steps

Environment configured! Now deploy your application:

Deployment

Deploy Sistema Financiero to Vercel, Railway, or other platforms

Build docs developers (and LLMs) love