How to access Heroku Config Vars in Bash - node.js

I'm trying to use process.env.REACT_APP_* process env variables in my react app after building it with npm run build on heroku, but my setup has a server and a client with all of the react code in a separate client folder in the root:
root
└ client/
└ build/
└ server.js
Even in my local development server this isn't working properly and I'm having to use a separate .env file in the client with the same key/value pair just prepended with REACT_APP. On my local, I'm running the server and the client concurrently, but on Heroku, it's built into a static app under client/build. The config vars that I defined on the heroku site is evidently not accessible in the static app because when I console log the process.env variable, I only see these variables:
NODE_ENV: "production"
PUBLIC_URL: ""
WDS_SOCKET_HOST: undefined
WDS_SOCKET_PATH: undefined
WDS_SOCKET_PORT: undefined
__proto__: Object
I have several REACT_APP_* variables defined on the heroku site, but none of them make it to the static build, but they're perfectly accessible on the server.
I need a way to access the variables on the static site and I'm currently exploring the possibility of manually writing a .env file to the client folder via bash scripts before running npm run build, but I ran compgen -vand set and viewed the values of all of those variables and the config vars don't appear to be any of them.
EDIT: I want to also note that I've tried this on a static-only heroku deploy which does NOT have a server and the root folder is the react app itself and I'm able to see my config var when I console.log(process.env):
NODE_ENV: "production"
PUBLIC_URL: ""
REACT_APP_TEST: "HELLO WORLD" <<===========
WDS_SOCKET_HOST: undefined
WDS_SOCKET_PATH: undefined
WDS_SOCKET_PORT: undefined

When heroku runs "npm run build", it is actually building the server.js file. Hence, the environment variables are injected in to server.js. If you console.log them some where inside the server.js, you will have them. The client is not actually build using the heroku, so no environment variables are injected. This is normal. You can change your project folder structure to fix this.

Related

I can't access my .env variables!! nodeJS

Server is running on PORT: undefined in undefined mode.
MongoDB database connected with HOST: localhost
used to get Server is running on PORT: 4000 in development mode. and suddenly it's undefined for both and every variable in my .env, like cloudinary .. stripe ...
You can add this snippet before starting mongoDB to see what's getting to your node process env variables:
console.log(process.env)
Also note that you can pass inline environment variables to node process like this:
PORT=4000 node ./my-script.js
To automatically load .env files, you might be using this package: https://github.com/motdotla/dotenv so be sure that you have all packages installed (npm install or yarn install, depending on what you are using).
One of the first things you should pay attention to is the file path. Check where your .env file is located in the project. If it is in the root of the project, there is no need to do anything. Otherwise, you must specify the path to the .env file.

ReactJS development environment works with my API when I use environment variables but my production server can't?

My CRA ReactJS project will work with my .env file and all the stuff I put in the file in development mode aka (my computer), but then when I try to deploy the code to my production server which uses PM2. I have a JS file that deploys the code to the server and builds it on the server, then calls for the app.config.json file that actually runs the web server, but only the NODE_ENV and PORT work, anything I use with REACT_APP_(whatever) doesn't and it just gives me undefined or null (depending on how I call the process.env)
{
apps : [
{
name : "Project-frontend",
script : "npx",
interpreter: "none",
args: "serve -s Project-frontend",
env: {
NODE_ENV: "production",
PORT: "3000",
REACT_APP_TEST: "eevee"
}
}
]}
I would like the REACT_APP_TEST to be able to display eevee on the production site.
Also I'm not sure if this would cause the problem but I do have a separate server with Nginx and SSL it runs through
Put your env variable to the .env file before building with react-scripts build (or anyway put the env variable before build).
serve command only serve a static file, it has no effect to send your env variable after build static file

Cannot set environment variables for react app inside node.js app. (heroku)

So I'm deploying a MERN stack app to heroku, and I have two .env files. One is for the nodejs backend, and one is for the react frontend. In heroku, you can set environment variables but they act essentially as a .env file in the root directory. However, my client folder is nested inside the node.js
If you're using react-scripts, you just need to preface any React env variables with REACT_APP_. This is how it knows where they belong when it is building your app. So just add them to your code and to the config vars on Heroku as REACT_APP_NAME_OF_YOUR_ENV_VAR and you should be good.
Here's the docs from Create React App on how to do it using react-scripts and adding the env variables and here it is for Heroku

db-migrate for node-postgres in next.js app not finding env variables on heroku

I'm trying to run db-migrate for postgres on heroku but cannot seem to figure out why it doesn't have the right env variables. Hoping for some guidance if someone else has encountered a similar problem.
I created a next.js app. Locally, I have a .env file with DATABASE_URL, etc. The app and migrations work just fine.
I pushed my app to heroku. The env variables are all defined in the heroku app config vars, so the app is working as expected. However, when I try to run db-migrate up or down, I get "Could not find database config file '/app/database.json'". I looked at the source and this only happens when process.env.DATABASE_URL is not defined. However, it is in my heroku app config vars, so I am confused as to why the migration cannot find the database URL. I thought the config vars would be pushed into node's process.env.
I am working around this by creating a new .env file in heroku every time I deploy but would prefer to fix this properly.

create react app cannot read environment variable after build

I have a react app , created with create-react-app then I build the app with command: npm run build
It's using serve to run the app after build, if we start the app with development code by running ENV=production npm run start it can read the process.env.ENV variable beacause I'm adding this plugins to webpack dev config
new webpack.DefinePlugin({
'process.env':{
'ENV': JSON.stringify(process.env.ENV),
}
}),
I also add the script above to webpack prod config, but if I try this command after build ENV=prod serve -s build, it cannot read the environment variable
How to fix this?
If you set all the environment variables inside the app.config.js, you can replace them after the build in the main.????????.chunk.js file.
A sample app.config.js could look like:
export default {
SOME_URL: "https://${ENV_VAR_1}"
SOME_CONFIGURATION: "${ENV_VAR_2}",
}
Leave the app.config.js file as is, without replacing the environment variables with their actual values. Then, create the optimized production build:
npm ci # if not already installed
npm run build
If the default webpack configurations are used, the contents of app.config.js will be bundled in build/static/js/main.????????.chunk.js. The values of the environment variables can be be envsubst, with a bash script like this:
main_chunk=$(ls build/static/js/main.*.js)
envsubst <$main_chunk >./main_chunk_temp
cp ./main_chunk_temp $main_chunk
rm ./main_chunk_temp
Note: In the above example, envsubst reads the actual variables set in the environment at runtime and literally replaces ${ENV_VAR_1} and ${ENV_VAR_2} with them. So, you can only run this once as the chunk is being over-written.
The reason why you can not read the ENV var is because:
(1) In development mode webpack watches your files and bundles you app on the fly. It also will read (because of the DefinePlugin) your process.env.ENV and will add it as a global variable. So it is basically piping variables from process.env to your JS app.
(2) After you've build your app (with webpack) everything is already bundled up into one or more files. When you run serve you just start a HTTP server that serves the static build files. So there is no way to pipe the ENV to you app.
Basically what the DefinePlugin does is add a var to the bundle. E.g.
new webpack.DefinePlugin({
'token': '12356234ga5q3aesd'
})
will add a line similar to this:
var token = '12356234ga5q3aesd';
since the JS files is static there is no way to change this variable after you've build/bundled it with webpack. Basically, when you do npm run build you're creating the compiled binary/.dll/.jar/... file and can no longer influence its contents via the plugin.
You can add a .env file to the root of your project and define your environment variables there. That will be your default (production) environment variables definition. But then you can have a local file called .env.local to override values from the default.
When defining your environment variables, make sure they start with REACT_APP_ so your environment variable definitions would look like this:
REACT_APP_SERVER_URL=https://my-awesome-app.herokuapp.com
Also, add this to .gitignore so you don't commit your local overrides:
.env*.local
Reference:
Adding Development Environment Variables In .env (create-react-app)
From create-react-app documentation:
Your project can consume variables declared in your environment as if
they were declared locally in your JS files. By default you will have
NODE_ENV defined for you, and any other environment variables starting
with REACT_APP_.
You can read them from process.env inside your code:
render() {
return (
<div>
<small>You are running this application in <b>{process.env.NODE_ENV}</b> mode.</small>
<form>
<input type="hidden" defaultValue={process.env.REACT_APP_NOT_SECRET_CODE} />
</form>
</div>
);
}

Resources