Environment Variables in NextJS are Undefined - javascript

I am using the next-auth library which requires the use of environment variables as follows:
Providers.GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
However, when I test out next-auth it is not working and it seems to me the reason why is because those variables are not loading properly. As such, I did a little test to see if I can access environment variables in my app and the test showed that I cannot.
This is how the test went:
// .env.local (root level)
NEXT_PUBLIC_ENV_LOCAL_VARIABLE="public_variable_from_env_local"
I then add the following code to my site:
<h2>test one start</h2>
{process.env.NEXT_PUBLIC_TEST_ONE}
<h2>test one end</h2>
<Spacer />
<h2>test two start</h2>
{process.env.TEST_TWO}
<h2>test two end</h2>
In this case, test one start shows up and test one end shows up, but the environmental variable does NOT show up. The same is true for test two start and test two end.
I did a similar test with console.log - namely:
console.log("test one", process.env.NEXT_PUBLIC_TEST_ONE)
console.log("test two", process.env.TEST_TWO)
That turns up as follows:
test one undefined
test two undefined
In short, for whatever reason I seem unable to load environment variables in my nextjs app. Not from next-auth, not in the code and not in a console.log. The variables are undefined and I do not know why.
Any ideas?
Thanks.

.env.* files are loaded when server starts. Hence, any modification in them is not applied unless you restart your dev/prod server.
Just halt the process (Ctrl+C/Z) and re-run next dev/next start to make them work. Note that you may also need to re-build the project (next build) before starting in production mode if you are using them in pages that are statically generated.

To be clear, according to the most recent docs, you are supposed to
place the variables in an .env.local file
then config your next.config.js file so it includes an env config
referencing your variables like this:
module.exports = {
env: {
secretKey: process.env.your_secret_here,
},
}
then you can call the variables on the client-side using the typical process.env.secret_here syntax. I may be mistaken but I do believe the NEXT_PUBLIC prefix exposes the env variables to the client-side and should ONLY be done in a dev environment to avoid security issues.

Searching the next.js documentation I found this:
// file: next.config.js
module.exports = {
env: {
customKey: 'my-value',
},
}
// Now you can access process.env.customKey
// For example, the following line:
// return <h1>The value of customKey is: {process.env.customKey}</h1>
// Will end up being:
// return <h1>The value of customKey is: {'my-value'}</h1>
So it seems, if you are using next.js version at or before 9.4 you place env variables into next.config.js
They also include one warning:
Next.js will replace process.env.customKey with 'my-value' at build time. Trying to destructure process.env variables won't work due to the nature of webpack DefinePlugin.
If you are using version 9.4+ the documentation says you can use .env.local files and prefix env variables with NEXT_PUBLIC_ to have them exposed in the browser.
Of note with this method is: In order to keep server-only secrets safe, Next.js replaces process.env.* with the correct values at build time. This means that process.env is not a standard JavaScript object, so you’re not able to use object destructuring.

Related

Unable to access process variable in Vue3JS Vite project

I am creating a vue3 application (created with Vite) that interacts with a smart contract written in Solidity and stored on Ropsten. Therefore I am using web3js to interact with my smart contracts and also web3.storage in order to store some images on IPFS. I have a .env file at the root of my project storing my API key for web3.storage :
VUE_APP_API_TOKEN=VALUE
VITE_API_TOKEN=VALUE
The problem is that apparently web3.storage expects the API token to be stored in process.env and I am unable to access the global process variable from my application. I am always getting an error Uncaught ReferenceError: process is not defined.
I think, this is linked to my usage of Vite instead of pure Vue3.
I tried to export process env in the vite.config.ts file with that code but it didn't work:
export default ({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd(), '') };
console.log(process.env.VITE_API_TOKEN) //Works fine: VALUE is logged
console.log(process.env.VUE_APP_API_TOKEN) //Works fine: VALUE is logged
return defineConfig({
plugins: [vue()]
});
}
How could I access the process variable from my vue files in order to get the values of my environment variable and make web3.storage work?
.env
VITE_WEB3_STORAGE_TOKEN="your_token"
SomeComponent.vue: (or any other file of your app, really):
console.log(import.meta.env.VITE_WEB3_STORAGE_TOKEN) // "your_token"
Note: as specified in vite documentation, only variables prefixed with VITE_ will be exposed:
To prevent accidentally leaking env variables to the client, only variables prefixed with VITE_ are exposed to your Vite-processed code.
If you're running the build script in CI you will need to make sure that you're creating / populating the relevant .env file before you run the build script.

How to make vue-cli-service fail if one of the process.env.VUE_APP_* environment vars cannot be resolved

I am using environment variables in my code as explained in the vue-cli-service environment variables section, and it surely works when the environment variables are defined.
But when one of the environment variables is undefined, it just replaces it with undefined.
Let's say if I introduce a new process.env.VUE_APP_MY_NEW_VAR, but then I don't set it in the environment, it will just put an undefined there.
I wanted to be sure that when building the project (npx vue-cli-service build [...]), none of the environment variables remain undefined.
One of my ideas is to check for undefined always, but it would happen at run time, not compile time.
Another idea is to create a shell script to check that all the variables are set before building, but that sounds quite manual.
Is there a way to do configure it and make it part of the build?
You can add a check in vue.config.js. For example
const REQUIRED_ENV_VARS = [
'VUE_APP_VAR_1',
'VUE_APP_VAR_2'
]
if (REQUIRED_ENV_VARS.some(env => typeof process.env[env] === 'undefined')) {
throw new Error('Required environment variables are missing')
}

Enviroment variables react

I have a react component which in development will redirect to a localhost url but in production to a different url. In my backend I have the same situation and there i solved it with a package called dotenv. I was wondering how someone would do this in a react front-end.
export default withRouter(function Login(props) {
useEffect(() => {
if(localStorage.getItem('jwt')){
props.history.push('/dashboard');
}
})
const handleLogin = () => {
window.location.href = "http://localhost:8000/auth/google";
}
return (
<LoginView handleLogin={handleLogin}/>
)
})
You can use dotenv to add environment variables to react as well. During app deployment(in the build process) the environment variables must be replaced with the corresponding URLs (as this is the most frequently encountered use case in front-end applications). This can be done while configuring the build process.
Here is an example using Webpack https://medium.com/#trekinbami/using-environment-variables-in-react-6b0a99d83cf5
The whole idea here is to create a file (called just .env) filled with
your environment variables. To prevent people from finding out your
local database password is the same one you use for every single one
of your accounts on the internet , I urge you to add the .env file to
your .gitignore. Your front-end code will refer to the same
environment variable (process.env.API_URL) on both environments
(development/production), but because you defined different values in
your .env files, the compiled values will be different.
I would suggest having a separate .env file for the react app as it should not be accidentally served with the website.
Create React App has a module(built around the node dotenv module) you can use for adding custom environment variables
https://create-react-app.dev/docs/adding-custom-environment-variables/
The environment variables are embedded during the build time. Since
Create React App produces a static HTML/CSS/JS bundle, it can’t
possibly read them at runtime. To read them at runtime, you would need
to load HTML into memory on the server and replace placeholders in
runtime, as described here. Alternatively you can rebuild the app on
the server anytime you change them.
Its depend on how you are using react.
If you are using react-script, you can go will above solution(https://create-react-app.dev/docs/adding-custom-environment-variables/).
But if you are using webpack, try to use DotenvPlugin in place of dotenv module (https://webpack.js.org/plugins/environment-plugin/).
In my opinion, pls don't follow method 1 use in medium link, as env should not be push on git but package.json need to be done.

Heroku process.env not showing config vars

I have a react app in a Heroku pipeline. Simply staging -> production.
In staging => Settings I have some config vars set up for the environment. However, when I console.log(process.env) I do not see them.
Am I supposed to be able to access these config vars in this manner? From what I've read, I should be able to access them from process.env. No?
I am using the following buildpack: https://github.com/mars/create-react-app-buildpack.git
Apparently you MUST name the config vars starting with REACT_APP_ and then you can access them via process.env.
This is all clearly outlined in the buildpack's documentation. I was just too dumb to actually check there :/
Append your Config Var name with the string 'React_App_' at the beginning (like React_App_Var_Name) and use this name in your ReactJs app. If this string is not appended and used, then it will return undefined.
For deploying production build, follow the steps mentioned in this link.

Confused by how many ways there are to set NODE_ENV

I'm trying to set a flag that informs my code whether it is in production or development. So far I've seen:
In VS Code's launch.json:
{ "configurations": { "env": "NODE_ENV": "development" } }
In Node's package.json:
{ "scripts": { "start": "NODE_ENV=production" } }
In Webpack's webpack.config.js:
module.exports = { "plugins": new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }) }
While running the code:
set NODE_ENV=production && node app
NPM packages:
https://www.npmjs.com/package/envify
Powershell:
$env:NODE_ENV="production"
I guess I'm just confused because by default I have around 4 of those set currently. How exactly do these interact? Are they all referring to the same variable? Should I only have one of these? Which ones overwrite the others?
I'd really prefer if there were just a single point to set this because it seems like every single module lets you specify it and as a result, I'm confused as to where it is actually being set. Also, is there anyway to access this flag on the client-side as well or is it server-side only?
In the scenario you've specified, the NODE_ENV environment variable will be initialized by the process that is actually executing your code. See the below excerpt from the environment variable wikipedia.
In all Unix and Unix-like systems, each process has its own separate set of environment variables. By default, when a process is created, it inherits a duplicate environment of its parent process, except for explicit changes made by the parent when it creates the child. At the API level, these changes must be done between running fork and exec. Alternatively, from command shells such as bash, a user can change environment variables for a particular command invocation by indirectly invoking it via env or using the ENVIRONMENT_VARIABLE=VALUE <command> notation. All Unix operating system flavors, DOS, and Windows have environment variables; however, they do not all use the same variable names. A running program can access the values of environment variables for configuration purposes.
So if you were to run your code using pm2, then pm2 will actually assign the NODE_ENV environment variable prior to executing your application. It uses a JSON file for options where you can specify your environment variables using the env property.
In short, all the ways to set your NODE_ENV are more or less equivalent, it just boils down to who starts your process.
Since environment variables are local to a machine (the environment) they are set locally and can't be set by a client.

Categories