Skip to content

Instantly share code, notes, and snippets.

@mpvosseller
Last active May 13, 2025 23:21
Show Gist options
  • Save mpvosseller/a448ef380bcbcc7f810e8b79661e2561 to your computer and use it in GitHub Desktop.
Save mpvosseller/a448ef380bcbcc7f810e8b79661e2561 to your computer and use it in GitHub Desktop.
Add support to Next.js for multiple "app environments" .env files (development, preview, staging, production)
// loadAppEnv.js
const fs = require('fs')
const dotenvFlow = require('dotenv-flow')
// This module loads .env files from the config/ directory based the "app
// environment" that it is being built for or is running in (e.g. development,
// preview, staging, beta, canary, production, etc..). The "app environment"
// is determined by APP_ENV (if defined) or NODE_ENV. It exports a set of
// environment variables which should be passed to Next.js as the env config.
//
// We do not place .env files in the project root because Next.js loads those
// based on NODE_ENV and is limited to just "development", "production", and
// "test". By using a distinct environment variable we can more easily create
// a "production" build (minified JavaScript, etc...) that uses "development"
// or "staging" application settings. This solution was based on the "proposed
// workaround" described in the following Next.js RFC:
// - https://github.com/vercel/next.js/discussions/25764
function throwErrorIfConflictingFilesDetected() {
// we throw an exception if .env files are found in the project root since
// they can conflict with ours. Someone probably just didn't realize we
// store .env files in ./config
fileNames = [
'.env',
'.env.local',
'.env.development',
'.env.development.local',
'.env.production',
'.env.production.local',
'.env.test',
'.env.test.local',
]
fileNames.forEach((path) => {
if (fs.existsSync(path)) {
throw new Error(
`env file detected in project root: ${path}. This project requires all .env files to be stored in ./config`
)
}
})
}
function loadAppEnv() {
throwErrorIfConflictingFilesDetected()
dotenvFlow.config({
path: 'config',
node_env: process.env.APP_ENV || process.env.NODE_ENV || 'development',
})
}
loadAppEnv()
// next.config.js
require('./loadAppEnv')
module.exports = {
//...
}
@Dilven
Copy link

Dilven commented Nov 23, 2022

thank you very much! Saved my day

@asp3
Copy link

asp3 commented Feb 5, 2023

Doesnt this need a return env in line 53?

@mpvosseller
Copy link
Author

@asp3 hmmm... I think you're right. However, it seems that code isn't even needed. Maybe it used to be needed but isn't any more. Will update.

@tappin-kr
Copy link

Why is this no longer needed? Support for runtime configs is still needed, right?

@mpvosseller
Copy link
Author

@tappin-kr the comments on Feb 5 and Feb 7 were related to a different revision so you can ignore. I still use the above code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment