React Environmental Variables are undefined with Dotenv - reactjs

I am using dotenv to create an environment variable to insert a base url into my API call using react, dotenv, and webpack.
When I call the variables in the code, I don't get any error other than them printing as undefined. What am I doing wrong?
Here is my webpack file
const webpack = require("webpack");
const Dotenv = require("dotenv");
dotenv.config();
module.exports = (env) => {
return {
plugins: [
new Dotenv(),
new webpack.ProvidePlugin({
process: "process/browser",
}),
new webpack.DefinePlugin({
'process.env': JSON.stringify(process.env)
})
],
};
};
Here are what the variables look like in the .env file in the root of my project
API_URL=http://localhost:8000
BASE_URL=https://my-url.com
And here is how I am accessing it in the code (with axios for auth)
axiosAuth: axios.create({
baseURL: `${process.env.BASE_URL}`,
timeout: 5000,
})

Like Shah already explain, the only thing that you need is add the prefix "REACT_APP" to your current variables..
Change this:
API_URL=http://localhost:8000
BASE_URL=https://my-url.com
To this:
REACT_APP_API_URL=http://localhost:8000
REACT_APP_BASE_URL=https://my-url.com

Set the values explicitly to be defined instead of the whole process.env. Try:
new webpack.DefinePlugin({
'process.env': {
API_URL: JSON.stringify(process.env.API_URL),
BASE_URL: JSON.stringify(process.env.BASE_URL),
}
})
And if you're using create-react-app, prefixing REACT_APP_ will also work and you could remove the define plugin and Dotenv.
example:
API_URL -> REACT_APP_API_URL // .env
usage: `process.env.REACT_APP_API_URL

Related

How can I pass environment variables by using dotenv in react app ? I get undefined

This is my react fontend app. to pass data from node.js backend, I need to successfully pass API's url. currently im setting the address to my localhost.
I am struggling to path process.env.API_URL to my config file.
my files structure is
.src
- config
* config.js
- .env
.webpack.config.js
my .env file is
API_URL=http://localhost:3006
my config file is below but im getting "undefined" as my console result here. clearly variable is not passing successfully.
console.log(process.env.API_URL)
const config = {
host: process.env.API_URL
};
export default config;
I have installed both "npm install dotenv --save" and "npm i dotenv-webpack"
Inside my Webpack.config.js is below. I feel like I am just so close to be working but I just cannot figure it out what's the problem here.
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
const dotenv = require('dotenv');
dotenv.config({ path: './.env' });
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.API_URL': JSON.stringify(process.env.API_URL),
}),
],
};
any suggestions is appreciated. thank you.
Well you have .env in src folder and you are trying to access it on same level as webpackConfig. So move the .env file on the same level as config or fix your import.

Heroku config vars returning undefined in production

I have an app that works fine locally using a .env file. However, when I add my variable to Heroku as described in the heroku CRA buildpack
But when I run my application, I get an undefined value.
How can I ensure that value populates properly?
Here's an example call I'm making in my app:
const xApiKeyHeader = { "x-api-key": process.env.REACT_APP_X_API_KEY };
const filteredProfiles = await fetch(
`${config.url}/profile/filteredProfiles`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
...xApiKeyHeader,
},
body: JSON.stringify({
...this.props.filter,
profession: this.state.professionValues,
}),
}
).then(...
Answer:
Added this to my webpack config (suggested in this thread heroku environment variables return undefined):
new webpack.DefinePlugin(({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.REACT_APP_X_API_KEY': JSON.stringify(process.env.REACT_APP_X_API_KEY)
})),
And set NODE_ENV to true in heroku config vars.

How to use process.env variables in browser running by Cypress

In the source code of my application (React based on create-react-app) I'm using env variables like so: process.env.REACT_APP_API_URL which are stored in my .env.* files.
But when I run the same application under the Cypress the process.env object is empty. How can I provide these variables to be used in React application when it's running under Cypress?
I know that I have a possibility to set Cypress env variables but it is not what I want - this is a different scope.
You can use the configuration API and do something like this on your plugins file. Set config.env = process.env which will set your entire node env for Cypress.
// cypress/plugins/index.js
module.exports = (on, config) => {
// modify env value
config.env = process.env
// return config
return config
}
You can also selectively assign the values that you want with config.env.YOUR_VAR = process.env.YOUR_VAR.
Updated in Cypress version 10.3.0 and above
In Cypress, environment variables (accessible via Cypress.env) doesn't share the same scope as OS-level environment variables. In order to make process.env variables available in Cypress, you should use a third party library, such as dotenv package, which is very popular.
npm install dotenv
Make sure this line of code sitting on top of your cypress.config.js
require('dotenv').config()
Now you're good to go using process.env, but only under that cypress.config.js file. As mentioned in another answer, you should leverage the Cypress.env() command by passing all process.env properties to Cypress environment variables, so that you can access those variables globally in Cypress
// cypress.config.js
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
config.env = {
...process.env,
...config.env
}
return config
}
}
})
Note that in Cypress version 10.0.0 and above, setupNodeEvents was added to replace the deprecated plugins file.
Now you can retrieve those variables by:
Cypress.env("your_proccess_env_property")
Create cypress.env.json file that contains your environment variables:
{
"api_url": "http://localhost:8080"
}
Then set process.env in your cypress/support/index.js:
...
before(() => {
process.env. REACT_APP_API_URL = Cypress.env("api_url");
})
For my use case, I was simply able to do the following.
// cypress.config.js
require('dotenv').config();
const { defineConfig } = require('cypress');
module.exports = defineConfig({
...,
env: {
...process.env,
},
});
Hopefully this helps anyone else in the future!
If you want to use the same variables, the same way as react app, while running only Cypress without an app (this is the reason why process.env is empty). You could add this in cypress.config.js
const dotenvOutput = require('dotenv').config()
then access the variables as
module.exports = defineConfig({
e2e: {
env: {
api_url: dotenvOutput.parsed.REACT_APP_API_URL,
},
You also need to make sure that the .env file is available where the cypress is ran.

Separate file for Environment Variable - ReactJS

I have this environment variable file that exports variable config depending on the NODE_END. Currently production and development variable are residing inside a one file, code below. How can I separate the file like development.js and production.js:
if(process.env.NODE_ENV === 'production') {
module.exports = {
API_URL: "https://test.co/api"
}
}
else {
module.exports = {
API_URL: "http://testbeta.co/api"
}
}
You can have a separate file to bridge them and export the intended module. For example, make three separate files index.js, development.js, and production.js on the same folder api.
// production.js
module.exports = {
API_URL: "https://e27.co/api"
}
// development.js
module.exports = {
API_URL: "http://e27beta.co/api"
}
// index.js
let exp
if (process.env.NODE_ENV === 'production') {
exp = require('./production.js')
} else {
exp = require('./development.js')
}
module.exports = exp
Then you can require it elsewhere like
// elsewhere.js
const api = require('path_to_api_folder')
If you using Webpack you can leverage the DefinePlugin plugin for exactly this purpose:
https://webpack.js.org/plugins/define-plugin/#use-case-service-urls
if(isProd) {
config.plugins.push(new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify("http://prod.example.com")
}));
} else {
config.plugins.push(new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify("http://dev.example.com")
}));
}
You could have 2 separate webpack configs, each with the appropriate SERVICE_URL'S.
// webpack.config.dev.js
plugins.push(new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify("http://dev-url.com")
}));
// webpack.config.prod.js
plugins.push(new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify("http://prod-url.com")
}));
To build, just pass webpack the appropriate config:
webpack --config webpack.config.prod.js
webpack --config webpack.config.dev.js

how to use webpack externals for config data in react/redux app

I'd like to use a config file in a react/redux app.
In this thread
How to store Configuration file and read it using React
i found a nice solution but i receive the following error when using require in my redux action file.
Module not found: Error: Cannot resolve module 'Config'
I managed to solve it with the following webpack config:
plugins:[
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
}
}),
],
externals: {
'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? {
api: "http://www.vitto.mt.it/eventi/api/public/"
} : {
api: "/react/eventi/api/public/"
})
},
and calling it:
var Config = require('Config');
But i still have to set manually the NODE_ENV value. How can i set it using an external file?

Resources