How to access environment variables from the front-end

46,136

Solution 1

There is a very simple way to to that:

Step one: Go to the root folder of your application and create a text file called .env.

Step two: Create your custom variables in the new file. Create React App(CRA) enforces the prefix REACT_APP on every custom variable. Please note that variables without the prefix are ignored during bundling.

REACT_APP_CLIENT_ID=jfjffffaddfeettgydgdffv
REACT_APP_KEY=aaddddawrfffvvvvssaa

Step three: Assign them to variables, print them to the screen etc, but they are read-only from your Javascript file.

console.log(process.env.REACT_APP_CLIENT_ID); 
console.log(process.env.REACT_APP_KEY);

Step four: There is a built-in environment variable called NODE_ENV. You can access it from process.env.NODE_ENV. This variable changes based on what mode you are currently in. When you run npm start, it is equal to ‘development’, when you run npm test it is equal to ‘test’, and when you run npm run build it is equal to ‘production’. This variable is special as it can be used to access different environment configurations based on your mode. For example, if you have different databases for your production and development (usually to prevent interference) you can use it to conditionally access certain variables. The fact that you cannot override NODE_ENV manually prevents developers from accidentally deploying a development build to production.

Step five: Open the .gitignore file. I like to put .env and other environment variables under #misc.

Why Isn’t It Working Even After Following These Processes?

  • Make sure you used the prefix REACT_APP on every variable

  • Confirm that the variable names on the .env file match the ones on your js file. For example,REACT_APP_KEY in .env versus process.env.REACT_APP_KY

  • If the development server was running, stop it then rerun using npm start it. I really struggled with this (variable is undefined error). Every time you update the .env file, you need to stop the server and rerun it, as the environment variables are only updated during build (variable is undefined error).

  • Remove quotations from the values of the variables.

Wrong

REACT_APP_KEY=”AHEHEHR”

Right

REACT_APP_KEY=AHEHEHR

Note: Putting Sensitive content to environment variables doesn’t make them safe. They are injected into the bundled file during the build process so anyone can see them by inspecting your files. I have found their greatest use to be hiding the information before pushing my code to a remote repository.

Solution 2

I case you want straight forward solution. there's 3rd party library for this called dotenv-webpack. More info here

const Dotenv = require('dotenv-webpack');

module.exports = {
  ...
  plugins: [
    new Dotenv()
  ]
  ...
};

Solution 3

You can use the following methods if you are from windows, if you are from linux then the methods are straight forward. You might not have encountered this problem with linux as dotfile are a thing in linux

Method 1 : dotenv in windows

This step might be necessary to access elements from a .env file in windows

npm install dotenv

then create a .env file in the root folder

API_KEY='SomeAPIkey'
API_PASS='ReallySecretPassword12345'

' is not necessary unless you have some strings seperated by space

and in your main.js file import the dotenv package

const dotenv = require("dotenv");

dotenv.config({ path: ".env" });

const key = process.env.API_KEY;
console.log(key);

if you are from linux you don't require the dotenv package for this to work.


Method 2: environment variables through terminal

+ in cmd

set API_KEY='SomeAPIkey'
set API_PASS='ReallySecretPassword12345'

+ in powershell

$env:API_KEY='SomeAPIkey'
$env:API_PASS='ReallySecretPassword12345'

+ in bash / wsl

export API_KEY='SomeAPIkey'
export API_PASS='ReallySecretPassword12345'

main.js

const key = process.env.API_KEY;
console.log(key);

The problem with method 2 is that your env variables live only as long as you keep the terminal session open. As soon as you close your terminal or shutdown your computer your env variables will be lost. I would recommend you to try and create a scripting file and add its filename to .gitignore

Solution 4

How to config the .evn file in React projects

  1. Simply create .env file.
  2. need to put your config in .env file, like
REACT_APP_FIREBASE_REALTIME_DB=https://sample.firebaseio.com/
REACT_APP_FIREBASE_API=FFYTYt67567yhhhmnbdfgjd7erehfjdhfjd

Note: You have to mention REACT_APP then you can mention your identifiers

eg: REACT_APP_FIREBASE_REALTIME_DB

  1. put the code your preferred files
process.env.REACT_APP_FIREBASE_REALTIME_DB
process.env.REACT_APP_FIREBASE_API

Solution 5

Webpack has that helps you send variables from the config to your react app, the Define plugin.
See here https://webpack.js.org/plugins/define-plugin/

Share:
46,136
José Carlos
Author by

José Carlos

Hi!!! I'm an analist and software developer. Right now, I'm working with python, node js, react js, javascript in projects like full stack developer or front-end developer or back-end developer. Maybe I have no the skills that you are looking for right now, but ... I can learn and adapt to several environments. Please, if you think that I can help you in your project, feel free to ask whatever you want about my CV or me.

Updated on March 19, 2022

Comments

  • José Carlos
    José Carlos about 2 years

    I have defined several environment variables in the compilation script. But, I have only access to this variables only from webpack.config.babel.js file and I need to get access to this variables in react code (front-end).

    I have found a way to do this here: https://blog.container-solutions.com/deploying-configurable-frontend-web-application-containers, but I don't think it would be a good idea to put in meta tags data like database passwords, for example. Despite of, trying to do only the way for .env file it doesn't work to me :(

    So, my question, is how can I get access to environment variables from the front-end?

    Edit I:

    I have applied the wise advice of @robi932 but it doesn't work to me :(

    webpack.config.babel.js

    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/client/index.html",    //where is our template
            filename: "../index.html",              //where we are going to put our index.html inside the output directory
            minify: {
                collapseWhitespace: true,
                removeComments: true,
                removeRedundantAttributes: true,
                removeScriptTypeAttributes: true,
                removeStyleLinkTypeAttributes: true,
                useShortDoctype: true
            }            
        }),
        new MiniCssExtractPlugin({
            filename: "css/bundle.css",
            minify: {
                collapseWhitespace: true,
                removeComments: true,
                removeRedundantAttributes: true,
                removeScriptTypeAttributes: true,
                removeStyleLinkTypeAttributes: true,
                useShortDoctype: true
            }             
        }),
        new webpack.DefinePlugin({
            URL_FEB_API: JSON.stringify(process.env.URL_FEB_API)
        })
    

    I define the const URL_FEB_API to use it later on my react-js code, but when I try to access to it, it doesn't work :(

    console.log("HomeLF1Content process.env.URL_FEB_API: " + URL_FEB_API);
    

    or

    console.log("HomeLF1Content process.env.URL_FEB_API: " + process.env.URL_FEB_API);
    

    This is my compiling scripts in package.json:

        "clean": "rm -rf ./dist",
        "compile-dev": "NODE_ENV=development URL_FEB_API=http://localhost:4000/api/feb/graphiql webpack -d --config ./webpack.config.babel.js --progress",
        "dev": "npm run clean && npm run compile-dev && cross-env NODE_ENV=development nodemon --exec babel-node src/server/server.js --ignore ./src/client"
    

    What am I doing wrong?

    Solution:

    Thanks to this link https://medium.com/@trekinbami/using-environment-variables-in-react-6b0a99d83cf5 give it by @Shubham Jain, finally I have found a good solution to define environment variables for the front-end.

    Then, I'm going to explain what have been the steps that I have followed to solve my problem.

    First, we need two .env files for each environment. Now, we have two environments: development and production. So, .env.development will be the file where we are going to config all our development variables and .env will be the file where we are going to config all our production variables.

    Second, to select one of those files created before, we need to say it to node which file to make the compilation, so in our compiling scripts we have to define a variable that we are calling NODE_ENV where we are going to initialize with "development" or "production".

    development scripts:

    "clean": "rm -rf ./dist",
    "compile-dev": "NODE_ENV=development webpack -d --config ./webpack.config.babel.js --progress",
    "dev": "npm run clean && npm run compile-dev && cross-env NODE_ENV=development nodemon --exec babel-node src/server/server.js --ignore ./src/client",
    

    production scripts:

    "clean": "rm -rf ./dist",
    "compile": "NODE_ENV=production webpack -p --config ./webpack.config.babel.js --progress",
    "start": "npm run clean && npm run compile && cross-env NODE_ENV=production babel-node src/server/server.js --ignore ./node_modules",
    

    Third, now, we are going to ad some code to our webpack.config.babel.js file to select the environment variables depending of the value of NODE_ENV variable.

    import webpack from "webpack";
    import path from "path";
    import dotenv from "dotenv";
    import fs from "fs";
    /**
     * Code to get the values of environment variables during compilation time for the front-end
     */
    //Get the root path. Our .env files and webpack.config.babel.js files are in the root path
    const currentPath = path.join(__dirname);
    const basePath = currentPath + "/.env";
    // We're concatenating the environment name to our filename to specify the correct env file!
    const envPath = basePath + "." + process.env.NODE_ENV;
    // Check if the file exists, otherwise fall back to the production .env
    const finalPath = fs.existsSync(envPath) ? envPath : basePath;
    // Set the path parameter in the dotenv config
    const fileEnv = dotenv.config({ path: finalPath }).parsed;
    // reduce it to a nice object, the same as before
    const envKeys = Object.keys(fileEnv).reduce((prev, next) => {
      prev[`process.env.${next}`] = JSON.stringify(fileEnv[next]);
      return prev;
    }, {});
    

    Fourth, in webpack.config.babel.js file too, in the plugin section, we have to add the access to this variables when compiling the project:

    plugins: [
        //With this entry we can get access to the environment variable for front-end
        new webpack.DefinePlugin(envKeys),
    ],
    

    And finally, to get access to these variables in the front-end, we can access to them easily with process.env.VARIABLE_NAME where VARIABLE_NAME is one of the variables defined in the files .env or .env.development.

    Please, vote the answer give it by @Shubham Jain, because his link has been very useful to me.

    • Shubham Jain
      Shubham Jain over 4 years
      You are talking about server's .env or client's .env?
    • José Carlos
      José Carlos over 4 years
      I'm taking about client's .env. With server environment variables I have no problem. Thanks.
    • Shubham Jain
      Shubham Jain over 4 years
      See if it helps medium.com/@trekinbami/…
    • darKnight
      darKnight about 2 years
      How will console.log(process.env) work in React code? React code will run in the browser where process will be undefined.
  • José Carlos
    José Carlos over 4 years
    Hi @robi932!!! I have applied your solution, but something I'm doing wrong because it doesn't work to me :(
  • robi932
    robi932 over 4 years
    did you restart the webpack server?
  • Jo_L
    Jo_L over 2 years
    Feel free to hit me up if this doesn't work for you
  • Adam Spiers
    Adam Spiers over 2 years
    This assumes that the OP is using create-react-app, but it seems they are not, or at least it is not guaranteed.