Static site generators often need environment-specific values (API endpoints, feature flags, analytics IDs) baked in at build time. This guide covers managing environment variables correctly for static site builds.
Why This Differs from Server-Side Environment Variables
Unlike a running server application that reads environment variables at runtime (see How to Manage Environment Variables and Secrets on a VPS), a static site's environment variables are resolved at build time and become part of the compiled, static output — there's no runtime process to read fresh values later.
Setting Environment Variables for a Local Build
echo "API_URL=https://api.yourdomain.com" > .env
echo "ANALYTICS_ID=UA-XXXXX" >> .env
Most modern static site generators (Next.js, Astro, Vite-based tools) automatically load a .env file during the build process.
Accessing Environment Variables in Build-Time Code
const apiUrl = import.meta.env.API_URL;
Exact access pattern varies by build tool — consult your specific framework's documentation, but the underlying concept (values substituted at build time into your compiled bundle) is consistent.
Critical Distinction: Build-Time vs Client-Exposed Variables
Any environment variable that ends up in your built JavaScript bundle is visible to anyone viewing your site's source — never put genuinely sensitive secrets (API keys with write access, private credentials) into client-facing build variables; see How to Secure API Keys and Prevent Credential Leakage for the broader principle.
Using Framework-Specific Prefixes for Client Safety
PUBLIC_API_URL=https://api.yourdomain.com
SECRET_BUILD_TOKEN=xyz123
Many frameworks require an explicit prefix (like PUBLIC_ or NEXT_PUBLIC_) for any variable intended to be exposed client-side, keeping unprefixed variables build-process-only (usable for things like fetching content from a CMS during build, without ending up in the shipped bundle).
Setting Environment Variables in CI/CD
- run: npm run build
env:
API_URL: ${{ secrets.API_URL }}
ANALYTICS_ID: ${{ vars.ANALYTICS_ID }}
See How to Manage Secrets in a CI/CD Pipeline — use your CI platform's secrets management for genuinely sensitive build-time values, and regular (non-secret) variables for things like analytics IDs that don't need the same protection.
Managing Different Values for Different Environments
.env.production
.env.staging
.env.development
Most build tools support environment-specific files, letting your staging build point to a staging API while production points to the production API, without manual reconfiguration between builds.
Rebuilding When Environment Values Change
Since values are baked in at build time, changing an environment variable requires triggering a new build/deployment — unlike a server application where you might just restart the process; factor this into how you think about "configuration changes" for a static site.
Common Errors
Environment variable shows as undefined in the browser despite being set — almost always a missing required prefix (framework-specific) needed for client-side exposure; verify your specific framework's convention for exposing build variables to client code.
Continue Reading
- How to Manage Environment Variables and Secrets on a VPS
- How to Manage Secrets in a CI/CD Pipeline
- How to Set Up Continuous Deployment for a Static Site with GitHub Actions
Browse more articles in Static Site Hosting & Frontend Deployment.