Environment Variables
Manage environment variables and secrets for your projects
Environment Variables
Environment variables let you configure your application without hardcoding values. This guide covers everything about managing environment variables in Parslinks.
What are Environment Variables?
Environment variables are key-value pairs that configure your application's behavior:
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=sk_live_1234567890
NEXT_PUBLIC_API_URL=https://api.example.comUse Cases
- Database Connections: Database URLs and credentials
- API Keys: Third-party service credentials
- Configuration: Feature flags, environment-specific settings
- Secrets: Authentication tokens, encryption keys
- Public Variables: Client-side configuration
Adding Environment Variables
Via Dashboard
- Navigate to your project
- Click Settings → Environment Variables
- Click Add Variable
- Fill in details:
Key: DATABASE_URL Value: postgresql://user:pass@host:5432/db Environment: Production - Click Save
Via CLI
# Add a single variable
parslinks env add DATABASE_URL postgresql://localhost:5432/db
# Add from .env file
parslinks env pull
parslinks env push
# Add multiple variables
parslinks env add KEY1=value1 KEY2=value2Via API
curl -X POST https://api.parslinks.com/v1/projects/PROJECT_ID/env \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "DATABASE_URL",
"value": "postgresql://localhost:5432/db",
"target": ["production"]
}'Bulk Import
Import multiple variables at once:
- Go to Environment Variables
- Click Import → Upload .env File
- Select your
.envfile - Review variables
- Choose environment
- Click Import
Or paste directly:
DATABASE_URL=postgresql://localhost:5432/db
API_KEY=sk_live_1234567890
REDIS_URL=redis://localhost:6379Environment Types
Production
Variables for your live, production deployment:
DATABASE_URL=postgresql://prod-db.example.com/db
API_KEY=sk_live_1234567890
NODE_ENV=productionUsed by:
- Production deployments
- Main branch deployments
- Custom domain deployments
Preview
Variables for preview deployments:
DATABASE_URL=postgresql://staging-db.example.com/db
API_KEY=sk_test_1234567890
NODE_ENV=stagingUsed by:
- Pull request deployments
- Branch deployments
- Preview URLs
Development
Variables for local development:
DATABASE_URL=postgresql://localhost:5432/db
API_KEY=sk_test_1234567890
NODE_ENV=developmentUsed by:
- Local development (download with CLI)
- Not used in Parslinks deployments
Variable Scope
Project Variables
Available to all environments in a project:
PROJECT_NAME=my-app
ORGANIZATION=acmeEnvironment-Specific Variables
Different values per environment:
Production:
DATABASE_URL=postgresql://prod-db/db
API_URL=https://api.production.com
Preview:
DATABASE_URL=postgresql://staging-db/db
API_URL=https://api.staging.com
Development:
DATABASE_URL=postgresql://localhost/db
API_URL=http://localhost:8000System Variables
Automatically injected by Parslinks:
PARSLINKS=1
PARSLINKS_ENV=production
PARSLINKS_URL=https://my-app.parslinks.app
PARSLINKS_GIT_COMMIT_SHA=abc123
PARSLINKS_GIT_COMMIT_MESSAGE="Add feature"
PARSLINKS_GIT_COMMIT_AUTHOR=[email protected]
PARSLINKS_GIT_BRANCH=main
PARSLINKS_REGION=us-east-1Public vs Private Variables
Private Variables (Server-Only)
Not exposed to the browser:
DATABASE_URL=postgresql://localhost/db
API_SECRET_KEY=sk_live_1234567890
JWT_SECRET=my-secret-keyCharacteristics:
- Only available on server/build time
- Never sent to browser
- Kept secure
- No naming prefix required
Public Variables (Client-Side)
Exposed to the browser:
# Next.js
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_ANALYTICS_ID=UA-1234567
# Vite
VITE_API_URL=https://api.example.com
VITE_ANALYTICS_ID=UA-1234567
# Create React App
REACT_APP_API_URL=https://api.example.com
REACT_APP_ANALYTICS_ID=UA-1234567Characteristics:
- Available in browser
- Visible in source code
- Must have specific prefix
- Don't use for secrets!
Framework-Specific Prefixes
| Framework | Public Prefix | Example |
|---|---|---|
| Next.js | NEXT_PUBLIC_ | NEXT_PUBLIC_API_URL |
| Vite | VITE_ | VITE_API_URL |
| Create React App | REACT_APP_ | REACT_APP_API_URL |
| Nuxt | NUXT_PUBLIC_ | NUXT_PUBLIC_API_URL |
| SvelteKit | PUBLIC_ | PUBLIC_API_URL |
Using Environment Variables
In Next.js
// Server-side (API routes, getServerSideProps, etc.)
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_SECRET_KEY;
// Client-side (components, browser)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// next.config.js
module.exports = {
env: {
CUSTOM_VAR: process.env.CUSTOM_VAR,
},
};In React (CRA)
// Must start with REACT_APP_
const apiUrl = process.env.REACT_APP_API_URL;
const analyticsId = process.env.REACT_APP_ANALYTICS_ID;
// Check if variable exists
if (!process.env.REACT_APP_API_URL) {
throw new Error("API URL not configured");
}In Vite
// Must start with VITE_
const apiUrl = import.meta.env.VITE_API_URL;
const mode = import.meta.env.MODE; // development or production
// With TypeScript
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_ANALYTICS_ID: string;
}In Node.js
// Load from .env file (local development)
require("dotenv").config();
// Access variables
const dbUrl = process.env.DATABASE_URL;
const port = process.env.PORT || 3000;
// Check required variables
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL is required");
}In Nuxt
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// Private (server-only)
apiSecret: process.env.API_SECRET,
// Public (client & server)
public: {
apiUrl: process.env.NUXT_PUBLIC_API_URL,
},
},
});
// In components
const config = useRuntimeConfig();
console.log(config.public.apiUrl);Managing Variables
Editing Variables
- Go to Environment Variables
- Find the variable
- Click Edit (pencil icon)
- Update value
- Click Save
- Redeploy for changes to take effect
Deleting Variables
- Find the variable
- Click Delete (trash icon)
- Confirm deletion
- Redeploy to apply changes
Copying Between Environments
Copy variables from one environment to another:
- Go to Environment Variables
- Select environment (e.g., Production)
- Click ⋮ → Copy to...
- Select target environment
- Choose which variables to copy
- Confirm
Renaming Variables
- Add new variable with new name
- Deploy and verify it works
- Delete old variable
- Deploy again
Security Best Practices
1. Never Commit Secrets
# ❌ DON'T commit .env files
.env
.env.local
.env.production
# ✅ DO add to .gitignore
echo ".env*" >> .gitignore2. Use Environment-Specific Values
# ✅ Different values per environment
Production: API_KEY=sk_live_real_key
Preview: API_KEY=sk_test_test_key
Development: API_KEY=sk_test_local_key
# ❌ Don't use production secrets in development3. Rotate Secrets Regularly
# Change secrets periodically
1. Generate new secret
2. Add as new environment variable
3. Deploy and test
4. Remove old secret
5. Update external services4. Use Secret Management
For high-security needs:
- AWS Secrets Manager
- HashiCorp Vault
- Azure Key Vault
- Google Secret Manager
5. Limit Access
- Only give team members access they need
- Use viewer role for read-only access
- Audit who has access to secrets
- Review access regularly
6. Monitor Usage
- Track when variables are accessed
- Alert on suspicious activity
- Log variable changes
- Review audit logs
Advanced Features
Variable Encryption
All environment variables are encrypted:
- At rest: AES-256 encryption
- In transit: TLS 1.3
- In memory: Secure enclave
- Access: Audit logged
Variable References
Reference other variables:
# Define base URL
API_BASE_URL=https://api.example.com
# Reference in other variables
API_USERS_URL=${API_BASE_URL}/users
API_POSTS_URL=${API_BASE_URL}/postsNote: Not all frameworks support this. Check framework documentation.
Conditional Variables
Set variables based on conditions:
# Using branch name
if [[ $PARSLINKS_GIT_BRANCH == "main" ]]; then
export ENV=production
else
export ENV=staging
fiEncrypted Secrets
For extra security, use encrypted secrets:
- Go to Environment Variables
- Toggle Encrypted Secret
- Variable is encrypted with project-specific key
- Only decrypted during deployment
CLI Commands
List Variables
# List all variables
parslinks env ls
# List for specific environment
parslinks env ls --environment production
# List with values (careful!)
parslinks env ls --show-valuesPull Variables
Download to local .env file:
# Pull production variables
parslinks env pull
# Pull specific environment
parslinks env pull --environment preview
# Pull to specific file
parslinks env pull --output .env.localPush Variables
Upload from local .env file:
# Push to production
parslinks env push
# Push specific file
parslinks env push .env.production
# Push to specific environment
parslinks env push --environment previewRemove Variables
# Remove a variable
parslinks env rm DATABASE_URL
# Remove from specific environment
parslinks env rm DATABASE_URL --environment preview
# Remove multiple
parslinks env rm VAR1 VAR2 VAR3Troubleshooting
Variable Not Available
Symptoms:
undefinedor empty value- Application errors
Solutions:
- Check variable name (case-sensitive)
- Verify correct environment
- Ensure redeploy after adding variable
- Check variable scope (production vs preview)
- For public vars, verify correct prefix
Variable Value Incorrect
Check:
- Recent changes to variable
- Environment selected
- Deployment uses latest configuration
- No typos in variable name
Solution:
- Redeploy after changing variables
- Clear build cache if needed
Public Variable Not Working
Common issues:
# ❌ Wrong prefix
API_URL=https://api.example.com
# ✅ Correct prefix (Next.js)
NEXT_PUBLIC_API_URL=https://api.example.comSolution:
- Add framework-specific prefix
- Rebuild application
- Check browser console for value
Variable Showing in Browser
Issue: Private variable visible in browser
Cause: Variable exposed during build:
// ❌ Don't do this
const config = {
apiKey: process.env.API_SECRET_KEY, // Bundled into client code!
};
// ✅ Do this (Next.js API route)
export default function handler(req, res) {
const apiKey = process.env.API_SECRET_KEY; // Server-only
// Use apiKey
}Best Practices
1. Naming Conventions
# ✅ Good naming
DATABASE_URL
API_SECRET_KEY
NEXT_PUBLIC_API_URL
MAX_UPLOAD_SIZE_MB
# ❌ Avoid
db
key
url
max2. Documentation
Document your variables:
# .env.example (commit this)
DATABASE_URL=postgresql://localhost:5432/mydb
API_SECRET_KEY=your-secret-key-here
NEXT_PUBLIC_API_URL=https://api.example.com
# README.md
## Environment Variables
- `DATABASE_URL`: PostgreSQL connection string
- `API_SECRET_KEY`: API authentication key
- `NEXT_PUBLIC_API_URL`: Public API endpoint3. Validation
Validate required variables:
// config.ts
const requiredVars = ["DATABASE_URL", "API_SECRET_KEY", "NEXT_PUBLIC_API_URL"];
requiredVars.forEach((varName) => {
if (!process.env[varName]) {
throw new Error(`Missing required environment variable: ${varName}`);
}
});4. Type Safety
Use TypeScript for type-safe environment variables:
// env.ts
export const env = {
database: {
url: process.env.DATABASE_URL!,
},
api: {
secretKey: process.env.API_SECRET_KEY!,
url: process.env.NEXT_PUBLIC_API_URL!,
},
} as const;
// Usage
import { env } from "./env";
console.log(env.database.url);5. Default Values
Provide sensible defaults:
const port = process.env.PORT || 3000;
const nodeEnv = process.env.NODE_ENV || "development";
const maxUploadSize = parseInt(process.env.MAX_UPLOAD_SIZE_MB || "10");Frequently Asked Questions
Do I need to redeploy after changing variables?
Yes! Environment variables are set during deployment. Change the variable, then trigger a new deployment.
Can I use the same variable name in different environments?
Yes! That's the whole point. Different values per environment:
Production: DATABASE_URL=prod-db
Preview: DATABASE_URL=staging-dbHow do I share variables with my team?
Use the dashboard or CLI to sync variables. Never share via email or chat.
Are environment variables backed up?
Yes, all changes are tracked. You can view history and restore previous values.
Can I import variables from another project?
Yes:
- Export from source project (CLI or dashboard)
- Import to destination project
- Review and confirm