i am creating react application using create-react-app,i am using node js as a backend development.
i can run it successfully in the local environment,but while having same application in the production build application doesn't set the "apiURL"
my backend url is=http://localhost:5001/
API_URL = process.env.REACT_APP_API_URL
actually i need to get my API_URL = http://localhost:5001
but i am getting API_URL is undefined in the production deploy
and on request of some backend api i am getting
http://localhost:3000/undefined/api/someapi
but actually i need to get the
http://localhost:5001/undefined/api/someapi
can any one help how can configure my environment variable dynamically depends on the host environment
sorry for my bad english
thanks in advance
You need to set different values of your variables depending on your environment. There're multiple possibilities, you can for example do it on script level in your package.json:
"scripts": {
"deploy:staging": "REACT_APP_API_URL=<paste-your-api-for-staging> ...",
"deploy:production": "REACT_APP_API_URL=<paste-your-api-for-production> ...",
}
Or you can use my personal favorite -> https://github.com/motdotla/dotenv for managing your env variables. It's based on different .env files for eg. .env.local or .env.production where you can set your values.
Related
I build a web app using react, webpack, docker and AWS.
I create a feature which depends on environment variable. So if the environment variable value is true, the feature will be showing on the frontend.
The problem is, when I changed the environment variable on the server (Webpack already done building the app, the app is already deployed and running), my feature is not showing. I guess due to the app cannot read the value changes on system environment variable.
How can I achieve this ? is it possible to do it ?
=====
I use dotenv webpack for managing my environment variables. I already set the systemvars to true to detect all environment variables from the system or .env file.
=====
So why am I doing this, because I dont want to make a Pull Request to push a new value for environment variables. I just want to reserve the environment variables name, and change the value directly from the server if the feature is ready to deployed. And if there is an error, I just need to change the environment variable to something and the feature is down.
You simply cant change environment variable. Evn variables loaded on compile/webpack load time. So once app start u cant change, process.env.
Solution as #jonrsharpe explains. You need to create, some sort of database. It could be memory or file or database. You read data from that. Expose a API, to update the data base.
Express sample:
global.enableFeature = false
app.post("/updateFeatureToggle", (req, res) => {
const enableFeature = req.body.enableFeature
global.enableFeature = enableFeature
res.send({success: "OK"})
})
In another file, read from global.enableFeature. This is in memory-based.
I have a react component which in development will redirect to a localhost url but in production to a different url. In my backend I have the same situation and there i solved it with a package called dotenv. I was wondering how someone would do this in a react front-end.
export default withRouter(function Login(props) {
useEffect(() => {
if(localStorage.getItem('jwt')){
props.history.push('/dashboard');
}
})
const handleLogin = () => {
window.location.href = "http://localhost:8000/auth/google";
}
return (
<LoginView handleLogin={handleLogin}/>
)
})
You can use dotenv to add environment variables to react as well. During app deployment(in the build process) the environment variables must be replaced with the corresponding URLs (as this is the most frequently encountered use case in front-end applications). This can be done while configuring the build process.
Here is an example using Webpack https://medium.com/#trekinbami/using-environment-variables-in-react-6b0a99d83cf5
The whole idea here is to create a file (called just .env) filled with
your environment variables. To prevent people from finding out your
local database password is the same one you use for every single one
of your accounts on the internet , I urge you to add the .env file to
your .gitignore. Your front-end code will refer to the same
environment variable (process.env.API_URL) on both environments
(development/production), but because you defined different values in
your .env files, the compiled values will be different.
I would suggest having a separate .env file for the react app as it should not be accidentally served with the website.
Create React App has a module(built around the node dotenv module) you can use for adding custom environment variables
https://create-react-app.dev/docs/adding-custom-environment-variables/
The environment variables are embedded during the build time. Since
Create React App produces a static HTML/CSS/JS bundle, it can’t
possibly read them at runtime. To read them at runtime, you would need
to load HTML into memory on the server and replace placeholders in
runtime, as described here. Alternatively you can rebuild the app on
the server anytime you change them.
Its depend on how you are using react.
If you are using react-script, you can go will above solution(https://create-react-app.dev/docs/adding-custom-environment-variables/).
But if you are using webpack, try to use DotenvPlugin in place of dotenv module (https://webpack.js.org/plugins/environment-plugin/).
In my opinion, pls don't follow method 1 use in medium link, as env should not be push on git but package.json need to be done.
I store the API base address in my environment class, and it gets reflected into
the bundles after build. What i need is a way to somehow liberate this
value from the build process so in case i wanna deploy the app under different
servers with different API addresses, I won't have to do another build only for the sake of a new URL.
My app is quite hefty and the build is really time-consuming.
Here is what is have in my environment.prod.ts :
export const environment = {
production: true,
configName: 'prod',
baseUrl: 'https://mpisitweb1/api'
};
I would try creating an environment.json that sits under your assets folder and make it publicly available. When your application is starting I'd do a request (On the same URL your serving from) to download that file which would contain the API baseUrl.
You'd have to store the value in Angular somewhere different though as you can't override the environment variable, might be best off putting it in a service somewhere that can be injected into the http Interceptor that way you can just specify "{BASE_URL}" as your base point and have the interceptor change it out to what's needed so the rest of your app isn't aware.
I have a react app in a Heroku pipeline. Simply staging -> production.
In staging => Settings I have some config vars set up for the environment. However, when I console.log(process.env) I do not see them.
Am I supposed to be able to access these config vars in this manner? From what I've read, I should be able to access them from process.env. No?
I am using the following buildpack: https://github.com/mars/create-react-app-buildpack.git
Apparently you MUST name the config vars starting with REACT_APP_ and then you can access them via process.env.
This is all clearly outlined in the buildpack's documentation. I was just too dumb to actually check there :/
Append your Config Var name with the string 'React_App_' at the beginning (like React_App_Var_Name) and use this name in your ReactJs app. If this string is not appended and used, then it will return undefined.
For deploying production build, follow the steps mentioned in this link.
Right now, whenever I want to deploy a node.js server to my production server, I need to change all the IP/DNS/username/password for my various connection to my databases and external APIs.
This process is annoying, is there a way to verify if the currently running node.js instance is in cloud9ide or actually my production joyent smartmachine?
If I am able to detemrine (in my running code) on which server my node.js instance is running , I'll add a condition that set the values to the prod or dev.
Thank you
Normally you should run a node app in production like this:
NODE_ENV=production node app.js
Applications with Express, Socket.IO and other use process.env.NODE_ENV to figure out the environment.
In development you can omit that and just run the app normally with node app.js.
You can detect the environment in your code like this:
var env = process.env.NODE_ENV || 'development';
loadConfigFile(env + '.json', doStuff);
Resources:
How do you detect the environment in an express.js app?
I think the easiest way to set the environment is to pass command-line argument to your application.
node ./server.js dev
In your script you need to handle this argument and set configuration what you need for it.
var env = process.argv[2] || 'dev';
switch (env) {
case 'dev':
// Setup development config
break;
case 'prod':
// Setup production config
break;
}
Also, i was created module that makes the configuration process a bit easier. Maybe it will help you.
Actually, I would not recommend to store configuration values like database connection information, passwords, access tokens and such inside of actual application code for the following reasons:
Hardcoding those values make it difficult to change them later on. You will have to release a new version of the application to change those values.
This is a serious security violation, because production-grade configuration data and passwords shouldn't be stored in code. It's very easy to leak this sensitive data.
The better approach would be to externalize this data and pass it to your application during execution. This is normally done by means of environment variables. You just need to define unique environment variable for each peace of data that needs to be changeable between different environments.
For example: DB_HOST, DB_USER, DB_PASSWORD. Then you could pass those values to you app in production this way:
$ NODE_ENV=production DB_HOST=1.2.3.4 DB_USER=someusername DB_PASSWORD=somerandompassword /bin/node app.js
Actually, this values could be encrypted and added to the codebase and then decrypted during the deployment. However, make sure that decryption key is stored securely in deployment system or provided interactively by the release engineer. Shippable allows to do this out of the box.
In the development environment it gets simpler, because you can use very convenient dotenv module. Just create a .env file in your project's root directory and add all variables to it:
DB_HOST=1.2.3.4
DB_USER=someusername
DB_PASSWORD=somerandompassword
But, make sure to exclude it from you VCS, because each developer probably would want to have personal configuration. You can create a .env.dist file to contain default configuration, which later could be used as a template: cp .env.dist .env.
For that you can just check it out with the help of environment variables and you can perform any actions.
if (process.env.NODE_ENV === "production") {
//do something in production
}
if (process.env.NODE_ENV !== "production") {
//do something in development
}