How to store Configuration file and read it using React
Asked Answered
C

5

132

I am new on react.js I have implemented one component in which I am fetching the data from server and use it like,

CallEnterprise:function(TenantId){


    fetchData('http://xxx.xxx.xx.xx:8090/Enterprises?TenantId='+TenantId+' &format=json').then(function(enterprises) 
    {
        EnterprisePerspectiveActions.getEnterprise(enterprises);
    }).catch(function()
    {
        alert("There was some issue in API Call please contact Admin");
        //ComponentAppDispatcher.handleViewAction({
        //    actionType: MetaItemConstants.RECEIVE_ERROR,
        //    error: 'There was a problem getting the enterprises'
        //});
    });
},

I want to store Url in configuration file so when I deployed this on Testing server or on Production I have to just change the url on config file not in js file but I don't know how to use configuration file in react.js

Can anyone please guide me how can I achieve this ?

Charlinecharlock answered 1/6, 2015 at 8:24 Comment(3)
Do you use webpack or some tool to compile the js code?Wormy
It would be common to send that value, set and read from an environment variable to the web page as a global value available within your JavaScript. Then, use it to fetch data.Xanthus
@PetrBela : yes I am using webpack to build bundle.js but I am taking about configuration file like web.config in .netCharlinecharlock
W
145

With webpack you can put env-specific config into the externals field in webpack.config.js

externals: {
  'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? {
    serverUrl: "https://myserver.com"
  } : {
    serverUrl: "http://localhost:8090"
  })
}

If you want to store the configs in a separate JSON file, that's possible too, you can require that file and assign to Config:

externals: {
  'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? require('./config.prod.json') : require('./config.dev.json'))
}

Then in your modules, you can use the config:

var Config = require('Config')
fetchData(Config.serverUrl + '/Enterprises/...')

For React:

import Config from 'Config';
axios.get(this.app_url, {
        'headers': Config.headers
        }).then(...);

Not sure if it covers your use case but it's been working pretty well for us.

Wormy answered 2/6, 2015 at 17:24 Comment(23)
You're welcome. BTW we've since learned that it's better to use JSON to avoid syntax errors. I've updated the code accordingly.Wormy
OMG, I am happy you were "listening". I went straight to a JSON import initially and it didn't work. Luckily your update let me on to the importance of executing JSON.stringify against my imported JSON.Haveman
@PetrBela What should be the format of config.json. How does it differentiate between production and localTheatheaceous
It doesn't. You might want to have two separate json files probably. Updated the example.Wormy
I cant get this to work: #36066332Scanderbeg
Hmm I haven't realized require parses the JSON file. Because externals expects a code to be evaluated, you need to stringify the JSON.Wormy
this doesn't work for me, I get this error : [Error: Cannot find module 'Config'] when using require('Config')Courtnay
guys from your webpack.config.js you need to define the path to the json file on your externals, for example require('./config.dev.json'), this is to prevent it from mistaken as node_modules. Then on your modules you can omit the path and require('config') if that is the variable you set from externalsSouthdown
I had to restart webpack after changeDow
Would you please share whole webpack.config or the application in github? ThanksDesultory
What if I want webpack not bundle seperate config file into output.bundle.js? If it would be a seperate from bundle, may I still require('Config')? ThanksDesultory
How did any of you get this to work? I do it exactly as suggested and I'm getting 'Cannot find module 'Config'', same as @amgohan.Fisk
It work for me in application but from eslint i get Unable to resolve path to module 'Config'Capelin
Works lika charm.Chignon
@PiotrGalas you should install the eslint-import-resolver-webpack packageGentle
Is there any way without restarting webpack, Updated Configurations can be accessed??Matta
Did anyone manage to create working configuration webpack file? It seem for me that only converting custom setup will help: github.com/facebookincubator/… I'm surprised that nobody mentioned it)Feltie
For me project created using create-react-app, process.env.ENV is undefined so i was not able to get env based values, but I am able to get value using process.env.NODE_ENV. Am I missing something?Iffy
One thing I'm having trouble with is that I'm already excluding the node_modules folder in the webpack.config.js file with the following: externals:[nodeExternals()] I have nodeExternals defined above as follows: var nodeExternals = require('webpack-node-externals')). Where does a custom reference to a configuration file fall into this setup?Chiaki
This answer is outdated, most folks use create-react-app now to make react apps, which does not provide a webpack.config.js anymore. If you are coming here after using create-react-app, do not eject your config! Do not create your own webpack hell. Use the REACT_APP_ env vars in the other solution, which get rolled up into the static builds.Sopor
I'm trying to use this, but in the browser I get the error "ReferenceError: require is not defined". Is there something else I need?Realism
Sorry but JSON.stringify(process.env.NODE_ENV === 'production' ? require('./config.prod.json') : require('./config.dev.json')) this line always returns the last file i.e. config.dev.json in both the modesVerso
Am I the only one who thinks checking for an environment string and reacting off that as a very poor solution?Spinney
A
93

If you used Create React App, you can set an environment variable using a .env file. The documentation is here:

https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables

Basically do something like this in the .env file at the project root.

REACT_APP_NOT_SECRET_CODE=abcdef

Note that the variable name must start with REACT_APP_

You can access it from your component with

process.env.REACT_APP_NOT_SECRET_CODE
Abisha answered 9/11, 2017 at 23:48 Comment(7)
just remember your variable name must start with REACT_APP_Sindhi
I have an ASP.NET Core app created with React template, and all I did was add an empty file under 'ClientApp' folder and put REACT_APP_MYSETTING=value in it, then refer to it as process.env.REACT_APP_MYSETTING in my JSX code, and it worked. Thanks!A1
.env does not work to me at all in create-react-app projectAnabolite
You will have to restart your project on npm once you've added .env to your root directoryMatusow
This seems like an anti-pattern. API endpoints are not secrets that should be defined in an environment variable. They're part of the definition of the app.Stapleton
@Stapleton the point isn't that it's a secret, it's that it changes by environment. I have an application that deploys to 1200 servers in four data centers across the country, on up to 8 clusters per data center, and local API endpoints are applied on each cluster. You don't want to hard-code something like that...Cromwell
@Stapleton also, these are not true environment variables, and should not be used to store secrets (hinted at by the docs sample variable REACT_APP_NOT_SECRET_CODE. Whatever data is put in these variables is sent to the end-user's browsers, so it's not a safe place to store "secret" information.Imperator
U
2

You can use the dotenv package no matter what setup you use. It allows you to create a .env in your project root and specify your keys like so

REACT_APP_SERVER_PORT=8000

In your applications entry file your just call dotenv(); before accessing the keys like so

process.env.REACT_APP_SERVER_PORT
Uda answered 9/11, 2017 at 23:52 Comment(1)
although I think you need to specify your keys starting with REACT_APP_Psychotechnology
T
1

In case you have a .properties file or a .ini file

Actually in case if you have any file that has key value pairs like this:

someKey=someValue
someOtherKey=someOtherValue

You can import that into webpack by a npm module called properties-reader

I found this really helpful since I'm integrating react with Java Spring framework where there is already an application.properties file. This helps me to keep all config together in one place.

  1. Import that from dependencies section in package.json

"properties-reader": "0.0.16"

  1. Import this module into webpack.config.js on top

const PropertiesReader = require('properties-reader');

  1. Read the properties file

const appProperties = PropertiesReader('Path/to/your/properties.file')._properties;

  1. Import this constant as config

externals: { 'Config': JSON.stringify(appProperties) }

  1. Use it as the same way as mentioned in the accepted answer

var Config = require('Config') fetchData(Config.serverUrl + '/Enterprises/...')

Topeka answered 2/10, 2018 at 1:45 Comment(1)
Your step 2 about webpack.config.js, if one is using create-react-app then there is no webpack config (or it is hidden). How to proceed in that case?Wolford
G
0

So not exactly a configuration file but you can also add environment variables in the package.json start script.

Before:

  "scripts": {
    "start": "react-scripts start",
    ....
  },

After:

  "scripts": {
    "start": "REACT_APP_TEST_ENV_VAR=TEST_DATA react-scripts start",
    ...
  },

You can read these now using the process.env.REACT_APP_TEST_ENV_VAR in your react code.

In a somewhat similar fashion you can also just move that env variable/config param to the command npm start command line.

So again before to launch your react app via command line: npm start

After: REACT_APP_TEST_ENV_VAR=TEST_DATA npm start

Gstring answered 25/4, 2023 at 4:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.