how can we use environment variables properly with env.config.js file in react.js(i got undefined after reload)

Viewed 49

When I'm running project with npm run start it's working fine after reloading my env.config.js giving variables undefined I have got a problem with env-config.js file. I implemented like this below

App.js file

import "./App.css";

function App() {
  const Query = window._env_.REACT_APP_QUERY;
  console.log(Query);
  return (
    <div className="App">
      <h1>hello world</h1>
    </div>
  );
}

export default App;

this is env-config.js file

window._env_ = {
  REACT_APP_GRANT: "grate",
  REACT_APP_CLIENT: "simple",
};

finally scripts in package-json file

 "scripts": {
    "start": "chmod +x .\\env.sh  && cp env-config.js .\\public/ && .\\env.sh && react-scripts start",
    "dev": "chmod +x ./env.sh && ./env.sh && cp env-config.js ./public/ && react-scripts start",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "build": "react-scripts build"
  },

I don't know about this file it was mentioned in scripts then I copied it here env.sh

#!/bin/bash

# Recreate config file
rm -rf ./env-config.js
touch ./env-config.js

# Add assignment 
echo "window._env_ = {" >> ./env-config.js

# Read each line in .env file
# Each line represents key=value pairs
while read -r line || [[ -n "$line" ]];
do
  # Split env variables by character `=`
  if printf '%s\n' "$line" | grep -q -e '='; then
    # tollerate = surrounded by blanks: ' = ' 
    varname=$(printf '%s\n' "$line" | sed -E 's/^([a-zA-Z_-]+) *= *(.*)$/\1/')
    varvalue=$(printf '%s\n' "$line" | sed -E 's/^([a-zA-Z_-]+) *= *(.*)$/\2/')
  fi

  # Read value of current variable if exists as Environment variable
  value=$(printf '%s\n' "${!varname}")
  # Otherwise use value from .env file
  [[ -z $value ]] && value=${varvalue}
  
  # Append configuration property to JS file
  echo "  $varname: \"$value\"," >> ./env-config.js
done < .env.local

echo "}" >> ./env-config.js

I'm running my project with git bash terminal with npm run start command

  1. I don't want to use .env file for some varables because I'm unable to overide with docker build command

  2. how can we get env-config.js variables without getting undefined after reload the project.

I'm not sure about env.sh file any more I couldn't understand what they coded earlier in that even don't know use of it

1 Answers

The comments in the script tell you what it is doing. It removes the env-config.js file, recreates it with the variables in .env file in the window._env_ variable. So, if you don't have a .env file, there will be no variables added to the window._env_ variable.

I suggest you remove the env.sh and use dotenv npm package: https://www.npmjs.com/package/dotenv

  1. Install dotenv
npm i dotenv
  1. Create .env file with the variables you want
REACT_APP_GRANT=grate
REACT_APP_CLIENT=simple
  1. Use dotenv inside env-config.js file
import * as dotenv from "dotenv";

// dotenv reads the .env file and adds the variables in
// there to process.env
dotenv.config()

window._env_ = {
  REACT_APP_GRANT: process.env.REACT_APP_GRANT,
  REACT_APP_CLIENT: process.env.REACT_APP_CLIENT,
};

Success!

If you set a variable like this: REACT_APP_GRANT=newgrant npm run start, dotenv, by default, will not overwrite newgrant for the one in .env. I believe the same will work when setting the variable in docker command line if you use docker run --env REACT_APP_GRANT=newgrant myapp

EDIT:

Apparently, reactjs already uses dotenv, so you might not need to install it. All you need to do is create the .env file and add the REACT_APP_ prefix to your variable names, like you are already doing. Then you can access them via process.env.REACT_APP_MY_VAR, as I did in my example.

Read more at https://create-react-app.dev/docs/adding-custom-environment-variables/

Related