This guide provides a comprehensive reference for all environment variables used in GitRead. These variables configure authentication, database connections, payments, and AI model access.
Overview
Environment variables are stored in .env.local for local development and configured in your deployment platform (Vercel) for production.
Never commit .env.local or any file containing secrets to version control. The .gitignore file excludes these files by default.
Quick setup
Create a .env.local file in your project root:
Then add all required variables listed below.
Clerk authentication
Clerk provides secure user authentication and session management.
Required variables
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
Variable details
| Variable | Description | Where to find |
|---|
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | Public key for client-side Clerk integration | Clerk Dashboard → API Keys |
CLERK_SECRET_KEY | Secret key for server-side authentication | Clerk Dashboard → API Keys (keep secure) |
NEXT_PUBLIC_CLERK_SIGN_IN_URL | URL path for sign-in page | Set to /sign-in |
NEXT_PUBLIC_CLERK_SIGN_UP_URL | URL path for sign-up page | Set to /sign-up |
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL | Redirect after successful sign-in | Set to / (home page) |
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL | Redirect after successful sign-up | Set to / (home page) |
Variables prefixed with NEXT_PUBLIC_ are exposed to the browser. Never use this prefix for secrets.
Supabase database
Supabase provides the PostgreSQL database for user credits, README history, and payment tracking.
Required variables
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGc...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGc...
Variable details
| Variable | Description | Where to find |
|---|
NEXT_PUBLIC_SUPABASE_URL | Your Supabase project URL | Supabase Dashboard → Project Settings → API |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Anonymous key for client-side operations (RLS protected) | Supabase Dashboard → Project Settings → API |
SUPABASE_SERVICE_ROLE_KEY | Service role key for admin operations (bypasses RLS) | Supabase Dashboard → Project Settings → API (keep very secure) |
Usage in code
The application uses two Supabase clients:
Client-side operations (app/utils/supabase.ts:1):
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
Server-side admin operations (app/api/generate/route.ts:11):
const supabaseAdmin = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
)
The SUPABASE_SERVICE_ROLE_KEY bypasses Row Level Security. Only use it in server-side API routes, never expose it to the client.
Stripe payments
Stripe handles credit purchases and payment processing.
Required variables
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
Variable details
| Variable | Description | Where to find |
|---|
STRIPE_SECRET_KEY | Secret key for server-side Stripe operations | Stripe Dashboard → Developers → API Keys |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Public key for client-side Stripe integration | Stripe Dashboard → Developers → API Keys |
Pricing configuration
The credit pricing is configured in the checkout session API (app/api/create-checkout-session/route.ts:22):
const pricePerCredit = 1.25; // $1.25 per credit
const price = credits * pricePerCredit;
To change pricing, modify this value in the code.
OpenRouter AI
OpenRouter provides access to Google’s Gemini AI model for README generation.
Required variable
OPENROUTER_API_KEY=sk-or-v1-...
Variable details
| Variable | Description | Where to find |
|---|
OPENROUTER_API_KEY | API key for OpenRouter access | OpenRouter Dashboard → API Keys |
Model configuration
The AI model is configured in the generation API (app/api/generate/route.ts:322):
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY
})
const response = await client.chat.completions.create({
model: "google/gemini-2.5-pro-preview-03-25",
messages: [
{ role: "system", content: "You are an expert technical writer." },
{ role: "user", content: prompt }
]
})
Application URL
The application URL is used for redirects and webhook endpoints.
Required variable
NEXT_PUBLIC_APP_URL=http://localhost:3000
Variable details
| Variable | Description | Usage |
|---|
NEXT_PUBLIC_APP_URL | Base URL of your application | Stripe redirects, webhook URLs, OAuth callbacks |
Usage in Stripe
The app URL is used for payment redirects (app/api/create-checkout-session/route.ts:42):
const session = await stripe.checkout.sessions.create({
success_url: `${process.env.NEXT_PUBLIC_APP_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/`,
// ...
})
Python ingestion API
The Python API handles GitHub repository ingestion and content extraction.
Required variable
PYTHON_API_KEY=your_secret_key_for_python_api
Variable details
| Variable | Description | Usage |
|---|
PYTHON_API_KEY | Authentication key for the Python ingestion service | Sent in x-api-key header to https://gitread-api.onrender.com/ingest |
Usage in code
The API key is used to authenticate requests (app/api/generate/route.ts:251):
const pythonApiUrl = "https://gitread-api.onrender.com/ingest";
const pythonApiKey = process.env.PYTHON_API_KEY!;
const response = await fetch(pythonApiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": pythonApiKey,
},
body: JSON.stringify({ repo_url: repoUrl }),
});
If you’re hosting your own ingestion service, update the pythonApiUrl in app/api/generate/route.ts.
Complete template
Here’s a complete .env.local template with all required variables:
# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
# Supabase Database
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
# Stripe Payments
STRIPE_SECRET_KEY=your_stripe_secret_key
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your_stripe_publishable_key
# OpenRouter AI
OPENROUTER_API_KEY=your_openrouter_api_key
# Application URL
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Python Ingestion API
PYTHON_API_KEY=your_secret_key_for_python_api
Validation
The application validates critical environment variables at runtime. For example, the OpenRouter API key is checked in app/api/generate/route.ts:17:
const openRouterApiKey = process.env.OPENROUTER_API_KEY
console.log("🔑 OpenRouter API Key:", openRouterApiKey ? "Present" : "Missing")
if (!openRouterApiKey) {
console.error("❌ OPENROUTER_API_KEY is not set in environment variables")
}
Security best practices
Follow these security practices to protect your application and user data.
- Never commit secrets: Ensure
.env.local is in .gitignore
- Use different keys: Use separate keys for development and production
- Rotate keys regularly: Update API keys periodically
- Limit key permissions: Use least-privilege access for service accounts
- Monitor usage: Watch for unusual API usage patterns
- Use Vercel environment variables: Store production secrets in Vercel, not in code
Troubleshooting
Missing environment variables
If you see errors about missing environment variables:
- Check that
.env.local exists in the project root
- Verify all required variables are set
- Ensure no typos in variable names
- Restart your development server after adding variables
Invalid credentials
- Verify keys are copied correctly (no extra spaces)
- Check that you’re using the correct environment (test vs. live)
- Ensure keys haven’t expired or been revoked
- Verify account access for each service
Variables not loading
- Restart the development server:
npm run dev
- Clear Next.js cache:
rm -rf .next
- Check for syntax errors in
.env.local
- Ensure file is named exactly
.env.local
Next steps