Environment Variables don't work in a nested JS file (React) - node.js

I'm trying to use environment variables in create-react-app.
I've prefixed all of the variables in my .env file with REACT_APP_ and installed/required dotenv.
However, I'm suspecting that the reason why my .env values aren't being read is because the script in which I'm calling them from isn't in the root folder where my .env file is located.
There's a quick overview of my project structure below
ROOT:
.env
VIEWS (folder):
view.js
I'm trying to access the .env variables in view.js by calling process.env.REACT_APP_MYVAR but it either doesn't return a value or returns something that isn't a string (which is the error my API is throwing, but it could be because that call is returning undefined)
Is this a known issue or is there any way I can fix this? I could just take the script out of that folder and put it in the root of my app but I'd rather keep the structuring of the app consistent

You don't need to "install/require" dotenv. If you are using create-react-app, this functionality is available with no additional install required.
You indicate that .env is in your root, but I suspect it may not actually be in your root. From your description, it sounds like you have it in your root source folder, but the .env file belongs in the root directory of your app (i.e. the same directory as your package.json file).
Here's a CodeSandbox (using create-react-app) that demonstrates using an environment variable in a nested file:
The contents of this sandbox includes:
.env (in the same directory as your package.json file)
REACT_APP_MYVAR=Here is my value for REACT_APP_MYVAR
src/index.js
import React from "react";
import ReactDOM from "react-dom";
import View from "./views/View";
function App() {
return <View />;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
src/views/View.js
import React from "react";
const View = () => {
return <div>My Var: {process.env.REACT_APP_MYVAR}</div>;
};
export default View;
The result that gets rendered is:
My Var: Here is my value for REACT_APP_MYVAR
The environment variable can be used in any of the js source files regardless of level of nesting.
If this doesn't help with your problem, please show the exact contents of your .env and view.js.

remove dotenv. Here is my git-repo for accessing REACT_APP_KEY. tell me if this solves your problem.
git-repo

Change .env to .env.development.local
Actually .env also work but if you have other .env.* file it will override .env,
.env is least priority in create-react-app
if you run project with npm start this file .env.development.local will override other env files
priority goes like this, form left to right
npm start: .env.development.local, .env.development, .env.local, .env

Related

Why is dotenv config method returning my system environmental variables?

I am trying to import strings from my .env file located in the root directory of my project into my index.js file. The dotenv config method is importing in all my system environmental variables instead.
Here is the structure of the project folder.
myapp/
.env
package.json
src/
index.js
commands/
I tried running my app out of different directories in the project folder thinking that config was using the cwd to check for the .env file. But neither worked. I have also tried setting the config() argument to "../index.env" because it is the path relative to index.js.
import { config } from "dotenv";
config();
const TOKEN = process.env.DISCORD_TOKEN;
Resulted in bringing in all the env variables like "PATH", "SHELL" etc

How to access dotenv variables in other files

I'm using the dotEnv package for my Node/Express server. I have the .env file in the root of my project. In the root I have a src folder where I import the package in my app.js file which is the entry point of my server like so: (root/src/app.js)
import dotenv from "dotenv";
dotenv.config();
This works fine and I can access it in the app.js without issue.
But I have a file called config.js in root/src/config that I also want to use the env variables. But when I use something like process.env.DB_HOST I get undefined. How can I use these env variables in this file (and subsequent files)? I managed to get it to work by using
require("dotenv").config({ path: `${__dirname}/../../.env` });
Is there an easier way to access the env variables without having to import the package with the correct path to the env in each file I want to use it in?

I can't access my environment variable in file.js

I define REACT_APP_ADMIN_URL in my .envrc file, i want to use it as a component link, but i get only empty or undefined
This my environment variable, in file .envrc
REACT_APP_ADMIN_URL="http://127.0.0.1:8000/admin"
in file consts.js i make
export const ADMIN_URL = process.env.REACT_APP_ADMIN_URL;
and in my page i make this
import { ADMIN_URL } from './Consts';
<Menu href={ADMIN_URL}>Admin</Menu>
but doesnt work, in my inspector console i get this
Admin
I think that you have to load the environment variables from the .env file on runtime, you can use dotenv package to do so.
Install the package using npm i dotenv
Create a .env file in the root directory of your project. Add environment-specific variables on new lines in the form of NAME=VALUE.
Put this line require('dotenv').config() before using the environment variables on your code.
process.env now has the keys and values you defined in your .env file

How to run node app from sub-directory with .env variables of that sub-directory?

I have a Node.js App called app.js and its stored in the directory B.
To run this script correctly it needs enviroment variables. These are stored in a file called .env, which is also in directory B.
In my app.js the env-variables are loaded via require("dotenv").config();
and I can then access them with e.g. process.env.SOME_VAR
So if I am currently located in directory B, I can just use node app and my app will execute just fine.
But if I go to the parent directory A and try to run my app via
node ./B/app
it will not execute, because it seems to have no access to the enviroment variables of the .env file.
So, my question is, how can I run my script from its parent folder, if I want to keep the .env file in the same directory?
You could use dotenv to load the the content of the environment variable i.e.
const dotenv = require('dotenv');
// ...
// Then go ahead to load the .env file content into process.env
dotenv.config({ path: '/full/custom/path/to/your/env/vars' });
you can set path using {path : '../.env'}.
require('dotenv').config({path : '../.env'});
Brilliant! it worked for me, I put my .env inside /vars folder
and used this line
require('dotenv').config({path : 'vars/.env'});
Instead of this line
require("dotenv").config();

Toggle between multiple .env files like .env.development with node.js

I want to use separate .env files for each mode (development, production, etc...). When working on my vue.js projects, I can use files like .env.development or .env.production to get different values for the same env key. (example: in .env.development: FOO=BAR and in .env.production: FOO=BAZ, in development mode process.env.FOO would be BAR, in production i'd be BAZ).
I'm working on an Express server and want to use these same kinds of .env files to store the port, db uri, user, pwd...
I know I can edit the scripts in package.json like this:
"scripts": {
"start": "NODE_ENV=development PORT=80 node ./bin/www",
"start-prod": "NODE_ENV=production PORT=81 node ./bin/www"
}
but this gets messy when using multiple variables.
I've tried using dotenv but it seems like you can only use the .env file. Not .env.development and .env.production.
Can I use the dotenv package or do I need another one? Or could I do this without any package at all?
You can specify which .env file path to use via the path option with something like this:
require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` })
The above two answers are both slightly off. let me explain. Answer from KyleMit below is missing ./ to indicate current directory.
the ./ indicates current directory in Node.js. The Second . prior to env indicates a hidden/private file. Thats why in KyleMits answer if the env file was not in the root of the PC it would never find it. The simplest way to do it in my opinion is to add a ./
this says "hey computer look in my current directory for this file".
//look in my current directory for this hidden file.
// List hidden files in dir: ls -a
require('dotenv').config({ path: `./.env.${process.env.NODE_ENV}` })
//I reccomend doing a console.log as well to make sure the names match*
console.log(`./.env.${process.env.NODE_ENV}`)
I'm using the custom-env npm package to handle multiple .env files. Just put this at the top of your code:
require('custom-env').env();
and it will load environment variables from the file .env.X, where X is the value of you NODE_ENV environment variable. For example: .env.test or .env.production.
Here is a nice tutorial on how to use the package.
From answers from above:
This is the final result that worked for me.
.env.dev file in src dir.
import path from 'path';
dotenv.config({ path: path.join(__dirname, `./.env.${process.env.NODE_ENV}`)});
For Typescript:
import dotenv from 'dotenv'
dotenv.config({ path: `.env.${process.env.NODE_ENV}` })
Install the dotenv package:
npm install dotenv
We need to get the .env file name based on NODE_ENV, it might be undefined, set default to development:
const envFileName = `.env.${process.env.NODE_ENV || "development"}`
Import the dotenv package and use it:
dotenv.config({ path: envFileName });
The official doc of dotenv does not recommend having multiple .env files.
"Should I have multiple .env files?
No. We strongly recommend against having a "main" .env file and an
"environment" .env file like .env.test. Your config should vary
between deploys, and you should not be sharing values between
environments."

Resources