Skip to main content

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

VariablePurposeUsageRequired
usernameDeveloper username for Git and PNPM setupGit configuration, registry authenticationYes
passwordDeveloper password for registry accessPNPM authentication, proxy setupYes
emailDeveloper email addressGit configuration, registry setupAuto-generated
gh_tokenGitHub personal access tokenRepository authenticationYes
proxyconfigProxy configuration choice (Z/B)Network proxy setupInteractive

Repository Management Variables

VariablePurposeDefaultDescription
pull_nextjsEnable repository cloningtrueControls whether to clone nextjs-web repo
default_branch_nextjswebGit branch to clonemainSpecific branch for repository cloning
default_depth_nextjswebGit clone depthunlimitedShallow 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.

VariablePurposeExample Value
NEXT_PUBLIC_MEGANAV_BANK_PAGESBank page routing configurationJSON array of paths
NEXT_PUBLIC_MEGANAV_NONAV_PAGESPages without navigationJSON array of paths
NEXT_PUBLIC_MEGANAV_TRUST_PAGESTrust service pagesJSON array of paths
NEXT_PUBLIC_FALLBACK_URL_LOGINLogin fallback URLhttps://client.schwab.com/Login/...
NEXT_PUBLIC_FALLBACK_URL_CONTACTContact fallback URLhttps://www.schwab.com/contact-us

Third-Party Service Configuration

VariablePurposeUsage
NEXT_PUBLIC_GOOGLE_MAPS_API_KEYGoogle Maps integrationMap components
NEXT_PUBLIC_JWPLAYER_KEYJW Player video serviceVideo components
NEXT_PUBLIC_CAPTCHA_SITE_KEYreCAPTCHA site keyForm validation
NEXT_PUBLIC_GEOLOCATION_URLGeolocation service endpointLocation services

CDN and Content Configuration

VariablePurposeDescription
NEXT_PUBLIC_AKAMAI_CDN_BYNDERBynder CDN endpointDigital asset management
NEXT_PUBLIC_AKAMAI_CDN_EDUCATIONEducation content CDNEducational resources
NEXT_PUBLIC_AKAMAI_CDN_PROSPECTSITECOLLECTIONProspect site CDNProspect-facing content
NEXT_PUBLIC_AKAMAI_CDN_RTCONTENTReal-time content CDNDynamic content delivery

2. Server-Side Variables

These variables are only available on the server and can contain sensitive information.

Authentication and Security

VariablePurposeSecurity Level
DRUPAL_RESTAPI_PASSWORDDrupal API authenticationHigh
LAUNCHDARKLY_SDK_KEYLaunchDarkly server keyHigh
BYNDER_ACCESS_TOKENBynder API access tokenHigh
COOKIE_ENCRYPTION_KEYCookie encryption keyCritical
FLAGS_SECRETFeature flags secretHigh

External Service Integration

VariablePurposeService
SFMC_CLIENT_IDSalesforce Marketing CloudEmail marketing
SFMC_CLIENT_SECRETSalesforce Marketing CloudEmail marketing
SIMPLECAST_API_KEYPodcast service integrationContent delivery
GOOGLE_GEOCODING_API_KEYServer-side geocodingLocation services

Internal Service Configuration

VariablePurposeEnvironment
RRBUS_HOST_NAMEInternal API gatewayhttps://restgateway-test.schwab.com
RRBUS_PASSKEYInternal API authenticationService authentication
RRBUS_CORRELATION_IDRequest correlationRequest tracking

3. Build and Deployment Variables

VariablePurposeSource
VERCEL_ENVDeployment environmentVercel platform
VERCEL_GIT_COMMIT_SHAGit commit hashVercel platform
VERCEL_GIT_COMMIT_REFGit branch referenceVercel platform
VERCEL_TARGET_ENVTarget environmentVercel 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.