Skip to main content

Overview

shrtnr requires several environment variables to connect to external services and configure authentication. This guide covers all required and optional variables.
Create a .env.local file in your project root for local development. Never commit this file to version control.

Required Variables

Database

POSTGRES_URL
string
required
Neon PostgreSQL connection stringFormat: postgresql://[user]:[password]@[host]/[database]?sslmode=requireExample:
POSTGRES_URL="postgresql://user:pass@ep-example-123.us-east-2.aws.neon.tech/neondb?sslmode=require"
Always include ?sslmode=require for secure connections to Neon
Where to get it:
  1. Go to Neon Console
  2. Select your project
  3. Navigate to Dashboard → Connection Details
  4. Copy the connection string (use pooled connection for serverless)

Redis Cache

UPSTASH_REDIS_REST_URL
string
required
Upstash Redis REST API endpointFormat: https://[your-db].[region].upstash.ioExample:
UPSTASH_REDIS_REST_URL="https://caring-falcon-12345.upstash.io"
Where to get it:
  1. Go to Upstash Console
  2. Select your Redis database
  3. Copy the “REST URL” from the REST API section
UPSTASH_REDIS_REST_TOKEN
string
required
Upstash Redis REST API authentication tokenExample:
UPSTASH_REDIS_REST_TOKEN="AXrfASQgZjQzNWYtZTU2Ny00YjhkLWJhMTUtZDg5ZTc2ODQ1ZWNh"
Where to get it:
  1. Same location as REST URL in Upstash Console
  2. Copy the “REST Token” (starts with AX...)
Keep this token secret - it grants full access to your Redis database

Authentication

AUTH_SECRET
string
required
Secret key used by NextAuth.js for JWT signing and encryptionRequirements:
  • Minimum 32 characters
  • Cryptographically random
  • Must be different between environments
Generate with:
openssl rand -base64 32
Example:
AUTH_SECRET="xvT9k2mP7nQ8rS4wZ1aB3cD5eF6gH7iJ8kL9mN0oP1qR2sT3uV4="
Never reuse the same AUTH_SECRET across different environments. Generate a new one for development, staging, and production.

Optional Variables

NEXT_PUBLIC_APP_URL
string
default:"http://localhost:3000"
The base URL of your application (used to construct short links)Used in: app/lib/links.ts:63 - Generates the full short URL when creating linksLocal development:
NEXT_PUBLIC_APP_URL="http://localhost:3000"
Production:
NEXT_PUBLIC_APP_URL="https://shrtnr.yourdomain.com"
This variable is prefixed with NEXT_PUBLIC_ so it’s available in the browser. The short URLs displayed to users will use this base URL.
NEXTAUTH_URL
string
default:"http://localhost:3000"
The canonical URL of your site (used for callbacks)Local development:
NEXTAUTH_URL="http://localhost:3000"
Production:
NEXTAUTH_URL="https://shrtnr.yourdomain.com"
Most platforms (Vercel, Netlify) auto-detect this. Only set manually if you experience redirect issues.
NODE_ENV
string
default:"development"
Node.js environment modeValues:
  • development - Local development with hot reload
  • production - Optimized production build
  • test - Testing environment
Example:
NODE_ENV="production"
Next.js automatically sets this during npm run dev (development) and npm run build (production)

Environment File Examples

# Database - Neon PostgreSQL
POSTGRES_URL="postgresql://user:password@ep-dev-123.us-east-2.aws.neon.tech/neondb?sslmode=require"

# Redis - Upstash
UPSTASH_REDIS_REST_URL="https://dev-redis-12345.upstash.io"
UPSTASH_REDIS_REST_TOKEN="AXrfASQgZjQzNWYtZTU2Ny00YjhkLWJhMTUtZDg5ZTc2ODQ1ZWNh"

# Authentication - NextAuth v5
AUTH_SECRET="dev-secret-xvT9k2mP7nQ8rS4wZ1aB3cD5eF6gH7iJ"
NEXTAUTH_URL="http://localhost:3000"

# Application URL (for generating short links)
NEXT_PUBLIC_APP_URL="http://localhost:3000"

Platform-Specific Setup

Add environment variables in the Vercel dashboard:
1

Navigate to Settings

Go to your project → Settings → Environment Variables
2

Add Variables

Add each variable with appropriate scope:
  • Production - Only production deployments
  • Preview - Pull request previews
  • Development - Local development with vercel dev
3

Redeploy

Trigger a new deployment for changes to take effect
Vercel automatically sets NEXTAUTH_URL based on your deployment URL

Security Best Practices

Never Commit Secrets

Add .env* to .gitignore to prevent accidentally committing secrets
.gitignore
.env
.env.local
.env.*.local
.env.production

Use Strong Secrets

Generate cryptographically secure random strings:
# 32 bytes, base64 encoded
openssl rand -base64 32

# 64 bytes for extra security
openssl rand -base64 64

Rotate Regularly

Change secrets periodically, especially:
  • After team member departures
  • If secrets may have been exposed
  • Every 90 days for compliance

Separate Environments

Use different credentials for:
  • Development
  • Staging
  • Production
This limits blast radius if secrets are compromised.

Validation

The application validates environment variables at startup. Missing required variables will cause errors:
app/lib/db.ts
import { neon } from '@neondatabase/serverless';
import { Redis } from '@upstash/redis';

// This will throw if POSTGRES_URL is not set
const sql = neon(process.env.POSTGRES_URL!, { fullResults: true });

// This will throw if Redis vars are missing
export const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL!,
  token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
The ! operator in TypeScript asserts the variable exists. If it doesn’t, you’ll get a runtime error.

Testing Configuration

Verify your environment variables are loaded:
# Test database connection
npm run test:db

# Start development server
npm run dev
If you see connection errors, double-check:
  1. Variable names are spelled correctly
  2. Values have no extra quotes or spaces
  3. .env.local is in the project root
  4. You’ve restarted the dev server after changes

Troubleshooting

Symptoms: App can’t connect to database/RedisSolutions:
  1. Verify .env.local is in project root (same level as package.json)
  2. Restart the dev server - env vars are loaded at startup
  3. Check for typos in variable names
  4. Ensure no quotes around values in .env files
# ✅ Correct
POSTGRES_URL=postgresql://...

# ❌ Wrong - extra quotes
POSTGRES_URL="postgresql://..."
Symptoms: Redirect loops, callback URL mismatchSolutions:
  1. Set NEXTAUTH_URL to match your domain exactly
  2. Include protocol: https:// not just shrtnr.com
  3. Verify trustHost: true in auth.ts for production
  4. Check that AUTH_SECRET is set and at least 32 characters
Symptoms: SSL SYSCALL error or connection refusedSolutions:
  1. Add ?sslmode=require to POSTGRES_URL
  2. Use the pooled connection string from Neon for serverless
  3. Verify your Neon project is not suspended (free tier limits)
Symptoms: 401 Unauthorized from UpstashSolutions:
  1. Verify UPSTASH_REDIS_REST_TOKEN is the REST token (not the Redis password)
  2. Check that URL and token are from the same database
  3. Ensure no trailing spaces in .env file
  4. Regenerate token in Upstash dashboard if needed

Next Steps

Database Setup

Initialize the PostgreSQL schema and run migrations

Deployment Guide

Deploy your application to production

Build docs developers (and LLMs) love