119

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 ?

Petr Bela
  • 7,368
  • 2
  • 25
  • 34
Dhaval Patel
  • 7,053
  • 6
  • 34
  • 64
  • 1
    Do you use webpack or some tool to compile the js code? – Petr Bela Jun 01 '15 at 09:06
  • 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. – WiredPrairie Jun 01 '15 at 10:41
  • 1
    @PetrBela : yes I am using webpack to build bundle.js but I am taking about configuration file like web.config in .net – Dhaval Patel Jun 02 '15 at 06:23

4 Answers4

136

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.

Amit Shah
  • 6,288
  • 5
  • 28
  • 47
Petr Bela
  • 7,368
  • 2
  • 25
  • 34
  • 2
    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. – Petr Bela Jan 12 '16 at 11:11
  • 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. – ctrlplusb Jan 12 '16 at 11:20
  • @PetrBela What should be the format of config.json. How does it differentiate between production and local – Aniket Mar 14 '16 at 09:06
  • It doesn't. You might want to have two separate json files probably. Updated the example. – Petr Bela Mar 15 '16 at 13:36
  • 1
    I cant get this to work: http://stackoverflow.com/questions/36065832/webpack-include-configuration-file-as-external-resource?noredirect=1#comment59778282_36065832 – Wexoni Mar 17 '16 at 16:51
  • 2
    Hmm I haven't realized require parses the JSON file. Because `externals` expects a code to be evaluated, you need to stringify the JSON. – Petr Bela Mar 17 '16 at 16:57
  • 22
    this doesn't work for me, I get this error : [Error: Cannot find module 'Config'] when using require('Config') – amgohan May 25 '16 at 12:27
  • 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 externals – Bryan Foong Dec 10 '16 at 20:41
  • 2
    I had to restart webpack after change – Vlad Vinnikov Mar 07 '17 at 19:03
  • 2
    Would you please share whole webpack.config or the application in github? Thanks – Barny Apr 20 '17 at 07:26
  • 4
    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')? Thanks – Barny Apr 20 '17 at 08:07
  • 3
    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. – ceebreenk May 22 '17 at 14:10
  • 1
    It work for me in application but from eslint i get `Unable to resolve path to module 'Config'` – Piotr Galas May 23 '17 at 13:42
  • Works lika charm. – Fernando Mendoza Jul 25 '17 at 19:26
  • 1
    @PiotrGalas you should install the eslint-import-resolver-webpack package – James Paterson Sep 06 '17 at 12:55
  • Is there any way without restarting webpack, Updated Configurations can be accessed?? – Lionel Dcosta Oct 24 '17 at 13:51
  • Did anyone manage to create working configuration webpack file? It seem for me that only converting custom setup will help: https://github.com/facebookincubator/create-react-app#converting-to-a-custom-setup I'm surprised that nobody mentioned it) – zkvarz Dec 15 '17 at 14:57
  • 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? – Sandeep Kumar May 21 '18 at 05:28
  • 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? – Michael Rut Jul 01 '19 at 14:14
  • 1
    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. – Josh Hibschman Jul 02 '19 at 19:02
  • 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? – waxingsatirical Nov 12 '19 at 13:41
  • 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 modes – Amit Shah Jan 24 '20 at 11:51
  • Am I the only one who thinks checking for an environment string and reacting off that as a very poor solution? – pwaterz Dec 03 '20 at 16:10
84

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
aris
  • 18,045
  • 1
  • 23
  • 26
  • 30
    just remember your variable name **must** start with `REACT_APP_` – Tomasz Madeyski Dec 21 '17 at 09:35
  • 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! – Neo Aug 24 '19 at 22:01
  • .env does not work to me at all in create-react-app project – user8620575 Sep 15 '19 at 20:42
  • 3
    You will have to restart your project on npm once you've added .env to your root directory – foyss Jan 02 '20 at 11:08
  • 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. – Rob Sep 06 '20 at 15:51
  • 2
    @Rob 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... – McGuireV10 Jan 21 '21 at 11:26
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
Max
  • 11
  • 4
Joshua Underwood
  • 843
  • 4
  • 13
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/...')

Fangming
  • 20,957
  • 4
  • 91
  • 84
  • 4
    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? – joedotnot Mar 06 '19 at 05:53