Environment Variables
This document provides an overview of environment variable management across the NextJS Web Monorepo, covering setup scripts, application configuration, and best practices for handling sensitive data and configuration values.
Overview
Environment variables in the monorepo serve multiple purposes:
- Application Configuration: Runtime behavior control for Next.js applications
- Service Integration: API keys, endpoints, and external service configuration
- Build-time Configuration: Deployment and build process settings
- Development Setup: Container initialization and development environment configuration
Environment Variable Sources
1. Setup Scripts (/home/schwab-scripts)
The container setup scripts use environment variables for automated configuration:
Core Setup Variables
| Variable | Purpose | Usage | Required |
|---|---|---|---|
username | Developer username for Git and PNPM setup | Git configuration, registry authentication | Yes |
password | Developer password for registry access | PNPM authentication, proxy setup | Yes |
email | Developer email address | Git configuration, registry setup | Auto-generated |
gh_token | GitHub personal access token | Repository authentication | Yes |
proxyconfig | Proxy configuration choice (Z/B) | Network proxy setup | Interactive |
Repository Management Variables
| Variable | Purpose | Default | Description |
|---|---|---|---|
pull_nextjs | Enable repository cloning | true | Controls whether to clone nextjs-web repo |
default_branch_nextjsweb | Git branch to clone | main | Specific branch for repository cloning |
default_depth_nextjsweb | Git clone depth | unlimited | Shallow clone depth control |
Network Configuration Variables
# Proxy Settings (ZScaler)
http_proxy=http://host.docker.internal:9000
# Proxy Settings (BlueCoast)
http_proxy=http://username:password@proxy.schwab.com:8080
2. Application Environment Files
Each application maintains its own .env.local file with application-specific configuration.
Common .env.local Structure
# Vercel Integration
VERCEL_PROJECT_ID="prj_..."
VERCEL_TEAM_ID="team_..."
VERCEL_ACCESS_TOKEN="..."
# NextJS Public Variables
NEXT_PUBLIC_VERCEL_ENV="development"
NEXT_PUBLIC_VERCEL_URL="localhost:3000"
# API Configuration
DRUPAL_RESTAPI_USERNAME="jsonapi.user"
DRUPAL_RESTAPI_PASSWORD="..."
# External Services
LAUNCHDARKLY_SDK_KEY="sdk-..."
BYNDER_ACCESS_TOKEN="..."
GOOGLE_GEOCODING_API_KEY="..."
Environment Variable Categories
1. Public Variables (NEXT_PUBLIC_*)
These variables are exposed to the browser and must not contain sensitive information.
Navigation and UI Configuration
| Variable | Purpose | Example Value |
|---|---|---|
NEXT_PUBLIC_MEGANAV_BANK_PAGES | Bank page routing configuration | JSON array of paths |
NEXT_PUBLIC_MEGANAV_NONAV_PAGES | Pages without navigation | JSON array of paths |
NEXT_PUBLIC_MEGANAV_TRUST_PAGES | Trust service pages | JSON array of paths |
NEXT_PUBLIC_FALLBACK_URL_LOGIN | Login fallback URL | https://client.schwab.com/Login/... |
NEXT_PUBLIC_FALLBACK_URL_CONTACT | Contact fallback URL | https://www.schwab.com/contact-us |
Third-Party Service Configuration
| Variable | Purpose | Usage |
|---|---|---|
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY | Google Maps integration | Map components |
NEXT_PUBLIC_JWPLAYER_KEY | JW Player video service | Video components |
NEXT_PUBLIC_CAPTCHA_SITE_KEY | reCAPTCHA site key | Form validation |
NEXT_PUBLIC_GEOLOCATION_URL | Geolocation service endpoint | Location services |
CDN and Content Configuration
| Variable | Purpose | Description |
|---|---|---|
NEXT_PUBLIC_AKAMAI_CDN_BYNDER | Bynder CDN endpoint | Digital asset management |
NEXT_PUBLIC_AKAMAI_CDN_EDUCATION | Education content CDN | Educational resources |
NEXT_PUBLIC_AKAMAI_CDN_PROSPECTSITECOLLECTION | Prospect site CDN | Prospect-facing content |
NEXT_PUBLIC_AKAMAI_CDN_RTCONTENT | Real-time content CDN | Dynamic content delivery |
2. Server-Side Variables
These variables are only available on the server and can contain sensitive information.
Authentication and Security
| Variable | Purpose | Security Level |
|---|---|---|
DRUPAL_RESTAPI_PASSWORD | Drupal API authentication | High |
LAUNCHDARKLY_SDK_KEY | LaunchDarkly server key | High |
BYNDER_ACCESS_TOKEN | Bynder API access token | High |
COOKIE_ENCRYPTION_KEY | Cookie encryption key | Critical |
FLAGS_SECRET | Feature flags secret | High |
External Service Integration
| Variable | Purpose | Service |
|---|---|---|
SFMC_CLIENT_ID | Salesforce Marketing Cloud | Email marketing |
SFMC_CLIENT_SECRET | Salesforce Marketing Cloud | Email marketing |
SIMPLECAST_API_KEY | Podcast service integration | Content delivery |
GOOGLE_GEOCODING_API_KEY | Server-side geocoding | Location services |
Internal Service Configuration
| Variable | Purpose | Environment |
|---|---|---|
RRBUS_HOST_NAME | Internal API gateway | https://restgateway-test.schwab.com |
RRBUS_PASSKEY | Internal API authentication | Service authentication |
RRBUS_CORRELATION_ID | Request correlation | Request tracking |
3. Build and Deployment Variables
| Variable | Purpose | Source |
|---|---|---|
VERCEL_ENV | Deployment environment | Vercel platform |
VERCEL_GIT_COMMIT_SHA | Git commit hash | Vercel platform |
VERCEL_GIT_COMMIT_REF | Git branch reference | Vercel platform |
VERCEL_TARGET_ENV | Target environment | Vercel platform |
Configuration Management Patterns
1. Environment-Specific Configuration
// Environment detection
const isDevelopment = process.env.NODE_ENV === 'development';
const isProduction = process.env.VERCEL_ENV === 'production';
// Conditional configuration
const apiUrl = isDevelopment
? 'http://localhost:3001'
: process.env.PRODUCTION_API_URL;
2. Feature Flag Integration
// LaunchDarkly configuration
const ldConfig = {
apiKey: process.env.LAUNCHDARKLY_API_KEY,
projectKey: process.env.LAUNCHDARKLY_PROJECT_KEY,
environment: process.env.LAUNCHDARKLY_ENVIRONMENT,
};
3. JSON Configuration Variables
Many configuration variables store JSON-encoded values:
// Parse JSON environment variables
const bankPages: string[] = process.env.NEXT_PUBLIC_MEGANAV_BANK_PAGES
? JSON.parse(process.env.NEXT_PUBLIC_MEGANAV_BANK_PAGES)
: [];
// Site ID mapping
const siteIds = JSON.parse(process.env.DRUPAL_SITE_IDS);
Setup Script Environment Handling
Interactive vs Automated Setup
The setup scripts support both interactive and automated configuration:
Interactive Mode
# Manual input prompts
read -p "Username:" username
read -p "GitHub Token:" gh_token
Automated Mode (useVars parameter)
# Use existing environment variables
./setup-env-git.sh useVars
./setup-env-pnpm.sh useVars
Variable Processing and Encoding
# URL encoding for special characters
password_encoded=$(urlencode "$password")
# Base64 encoding for authentication
auth_token=$(echo -ne "$username:$password" | base64)
Turbo Configuration Integration
Environment variables are managed at the Turborepo level in turbo.json:
{
"globalEnv": [
"NEXT_PUBLIC_*",
"NODE_ENV",
"VERCEL_*"
],
"tasks": {
"build": {
"env": [
"NEXT_PUBLIC_SEARCH_SUGGEST",
"NEXT_PUBLIC_SEARCH_HOME",
"NEXT_PUBLIC_GEOLOCATION_URL"
]
}
}
}
Security Best Practices
1. Variable Classification
- Public Variables: Use
NEXT_PUBLIC_prefix, safe for browser exposure - Server Variables: No prefix, server-side only
- Sensitive Data: Never commit to version control
2. Access Control
// Validate environment variables exist
const requiredEnvVars = [
'DRUPAL_RESTAPI_PASSWORD',
'LAUNCHDARKLY_SDK_KEY'
];
requiredEnvVars.forEach(envVar => {
if (!process.env[envVar]) {
throw new Error(`Required environment variable ${envVar} is not set`);
}
});
3. Certificate and Key Management
Long certificate and key values are stored as environment variables:
# SSL certificates for corporate environment
RRBUS_URL_CA_CERT_KEY="-----BEGIN PRIVATE KEY-----\n..."
RRBUS_URL_CA_PEM="-----BEGIN CERTIFICATE-----\n..."
Development Workflow Integration
1. Local Development
# Load environment variables for development
pnpm dev # Automatically loads .env.local files
2. Testing
# Override for testing
process.env.NODE_ENV = 'test';
process.env.INIT_NEXT_NAV_QUERY = '';
3. Build Process
Environment variables are automatically included in the build process based on Turbo configuration.
Application-Specific Variables
www.schwab.com
- Content Management: Drupal integration, Sanity CMS configuration
- Marketing: SFMC integration, tracking configuration
- Media: JWPlayer, Bynder asset management
client.schwab.com
- Authentication: CXP integration, session management
- Client Services: Internal API configuration
- Channel Configuration: Client-specific feature flags
meganav-mfe
- Micro-Frontend: Cross-application navigation configuration
- Webhook Integration: Deployment automation
- API Protection: Rate limiting and authentication
Troubleshooting
Common Issues
Missing Environment Variables
# Check if variable is set
echo $VARIABLE_NAME
# List all environment variables
printenv | grep SCHWAB
Invalid JSON Configuration
// Safe JSON parsing
let config = [];
try {
config = JSON.parse(process.env.CONFIG_VAR || '[]');
} catch (error) {
console.error('Invalid JSON in CONFIG_VAR:', error);
}
Network Configuration Issues
# Verify proxy settings
pnpm config list | grep proxy
# Test registry access
pnpm ping
Debugging Commands
# Check pnpm configuration
pnpm config list
# Verify Turbo environment
turbo run build --dry-run
# Test environment variable loading
node -e "console.log(process.env.NEXT_PUBLIC_VERCEL_URL)"
Best Practices
1. Variable Naming
- Use descriptive, consistent naming conventions
- Group related variables with common prefixes
- Follow Next.js conventions (
NEXT_PUBLIC_for client-side)
2. Documentation
- Document all environment variables and their purposes
- Maintain example values for development setup
- Keep security classifications up to date
3. Validation
// Runtime validation
const config = {
apiUrl: process.env.API_URL || 'http://localhost:3000',
timeout: parseInt(process.env.TIMEOUT || '5000', 10),
enableFeature: process.env.ENABLE_FEATURE === 'true'
};
// Type safety with Zod
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
API_KEY: z.string().min(1),
PORT: z.coerce.number().positive()
});
const env = envSchema.parse(process.env);
4. Environment Separation
- Use different values for development, staging, and production
- Implement environment-specific fallbacks
- Validate critical variables at application startup
The environment variable system ensures secure, flexible configuration management across the entire NextJS Web Monorepo ecosystem while maintaining separation of concerns and following security best practices.