Last active
October 11, 2024 20:20
-
-
Save stefan-girlich/4974d9d57bcbad35a973ba02774eb999 to your computer and use it in GitHub Desktop.
use Envalid to validate and expose Next.js client-side and server-side variables
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { cleanEnv, Spec, str, ValidatorSpec } from 'envalid' | |
// https://github.com/af/envalid | |
/** | |
* This module is the single source of truth for application environment configuration. | |
* When imported as a TypeScript module, it provides runtime access to validated environment variables. | |
* When executed as a script, it may cover the following use cases: | |
* - validate current environment | |
* - load current environment beforehand (when CLI flag --force-load-env is used) | |
* - print empty environment configuration as .env-compatible string (when CLI flag --print-env is used) | |
* - print valid environment configuration as .env-compatible string (when CLI flag --print-env is used) | |
* This module detects if it is executed in a client-side environment and excludes server-only variables, see: | |
* https://nextjs.org/docs/basic-features/environment-variables#exposing-environment-variables-to-the-browser | |
*/ | |
const FORCE_LOAD_CLI_FLAG = '--force-load-env' | |
const PRINT_ENV_CLI_FLAG = '--print-env' | |
const printEnvCliFlagProvided = process.argv?.includes(PRINT_ENV_CLI_FLAG) | |
const forceLoadCliFlagProvided = process.argv?.includes(FORCE_LOAD_CLI_FLAG) | |
if (forceLoadCliFlagProvided) { | |
console.info('Force-loading environment ...') | |
const { loadEnvConfig } = require('@next/env') | |
loadEnvConfig(process.cwd()) | |
} | |
// ========== environment definition and validation ========== | |
const isServer = typeof window === 'undefined' | |
const envVars = { | |
NEXT_PUBLIC_CLIENT_VAR: process.env.NEXT_PUBLIC_CLIENT_VAR, | |
SERVER_VAR: process.env.SERVERSIDE_VAR, | |
} | |
type EnvKey = keyof typeof envVars | |
const optionalVarOpts: Spec<string> = { default: undefined } | |
const serverVarOpts = isServer ? undefined : optionalVarOpts | |
const envConfig: Record<EnvKey, ValidatorSpec<string>> = { | |
NEXT_PUBLIC_CLIENT_VAR: str(), | |
SERVER_VAR: str(serverVarOpts), | |
} | |
if (printEnvCliFlagProvided) { | |
console.info('Printing empty .env configuration ...') | |
const emptyEnvConfigString = Object.keys(envConfig) | |
.reduce((acc, curr) => [...acc, `${curr}=`], []) | |
.join('\n') | |
console.info(`${emptyEnvConfigString}\n`) | |
} | |
const env = cleanEnv(envVars, envConfig) | |
if (printEnvCliFlagProvided && forceLoadCliFlagProvided) { | |
console.info('Printing current valid .env configuration ...') | |
const validEnvConfigString = Object.entries(env) | |
.reduce((acc, [key, value]) => [...acc, `${key}=${value}`], []) | |
.join('\n') | |
console.info(`${validEnvConfigString}\n`) | |
} | |
export default env |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is solid. Thanks.