-
Notifications
You must be signed in to change notification settings - Fork 38
Description
References:
- Variables loaded with dotenv-vault not prefixed with NEXT_ are undefined (server side) #261
- Dotenv Vault not working on Vercel vercel/vercel#10607
Since Vercel doesn't allow dynamic env load for server env key, so i decided to make this workaround for other user to use. Here's I'm making an example on Next.js project.
- Create
.env.keyfile containingDOTENV_KEY - Create this script in
/scripts/load-env.tsor any other place you wish
import { config } from "dotenv";
import { writeFile } from "fs/promises";
const main = async () => {
const keyEnv = config({ path: ".env.key" });
const DOTENV_KEY = keyEnv.parsed?.DOTENV_KEY || process.env.DOTENV_KEY; // If DOTENV_KEY not found in .env.key, get it from process.env
if (!DOTENV_KEY) {
throw new Error("No DOTENV_KEY found in .env.key or process.env");
}
const envs = config({ DOTENV_KEY }); // If DOTENV_KEY found, get the .env.vault, load it to get shared env variables
if (!envs.parsed || Object.keys(envs.parsed).length === 0) {
throw new Error("No .env.vault found or it is empty");
}
try {
await writeFile(
".env",
// eslint-disable-next-line prefer-template
"# This file is generated by /scripts/load-env.ts\n" +
"# DO NOT ATTEMPT TO EDIT THIS FILE\n" +
Object.entries(envs.parsed)
.map(([key, value]) => `${key}=${value}`)
.join("\n")
);
console.log("Successfully loaded .env.vault to .env");
} catch (error) {
console.error("Failed to load .env.vault to .env", error);
}
};
main();- Add
env:loadto your scripts and edit existing script like this
"scripts": {
"dev": "pnpm env:load && start http://127.0.0.1:3000 && next dev",
"build": "pnpm env:load && prisma generate && next build",
"env:load": "ts-node ./scripts/load-env.ts"
}💡 You can change pnpm with any other package manager you want
So basically, it loaded the content of the .env.vault to .env and then proceed to build the app with .env keys, i think this way is more safe and straightforward than prefixing the keys with NEXT_PUBLIC_ since the key prefixed with that can be bundled in the JavaScript file.
And also this helps executing cli that are depends on env vars like prisma db pull more easier, if you are collaborating with other devs, they just need to load the env first using pnpm env:load after pulling from the repo.
Let me know what you think. Thank you!