I need to set the proxy
value in my package.json
at runtime, like with an environment variable. How could this be done?
// package.json
{
"name": "demo",
"proxy": process.env.MY_PROXY_VAL , // <- how?
"dependencies": {},
"scripts": {},
}
Thanks.
Can package json use environment variables? By using dotenv and cross-var together, we're able to read in whichever . env files we want, or consume existing environment variables (from cli, bash_profile, CI, etc) and then easily substitute them into our package. json scripts and it works across development platforms!
To configure the proxy, you'll need to add the following line to your package. json . Then, in your React app, you can make API requests by using relative paths. For example, http://localhost:8000/api/todos becomes /api/todos .
proxy field in package. json is used to proxy all requests from frontend domain to backend. For example, you have: Backend (REST API): localhost:5000/api/user/:id.
So I am converting my comment into an answer, since I think it is important to point out an actual solution to this problem.
I was searching for that exact same answer, and also tried setting the HTTP_PROXY
and HTTPS_PROXY
variables via an .env file, and also directly from within a script. However this does not solve the problem since this will overwrite the system proxy settings for the local machine, which I don't think was something the OP intended to do. The result can be that you cannot load npm packages anymore, because of incorrect system proxy settings.
Instead, there is a way of manually configuring the proxy for a CRA in development, as pointed out by the official docs: https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually
With this you should create a local setupProxy.js
file under the /src
folder of the project, which will then override the proxy set in package.json
.
Of course then you have to make sure that all the paths are correctly set, but it works well and you have fine grained control over which pages in your app will be proxied and which will not.
To target specifically your question about how to set the proxy via an environment variable, here is an example how you could do it with the setupProxy
approach and the createProxyMiddleware
:
// Sample of how to setup a proxy middleware with environment variables
//// file: <project_root>/src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/rest',
createProxyMiddleware({
target: process.env.REACT_APP_PROXY_HOST,
changeOrigin: true,
})
);
};
//// file: <project_root>/.env
REACT_APP_PROXY_HOST=https://localhost:6700
In this case I only wanted to proxy requests targeted to the /rest
endpoint, for which I created a new endpoint. All other requests will still go to the default localhost:3000
Url, serving the react app.
The host is defined via the environment variable REACT_APP_PROXY_HOST
. I defined the variable in the local .env
file, but you could also directly set it inside a script in package.json
if needed.
Update:
Even though the original question was already solved for me, I had an additional issue trying to forward requests to a server running on https
.
The previous development setup has been fine with the static proxy set in package.json
. However when using the createProxyMiddleware
and targeting a server running on https with certificates, the path to the used certificate has to be provided.
// Sample of how to setup a proxy middleware with environment variables
// targeting a server running on https
//// file: <project_root>/src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
const fs = require('fs');
const protocol = JSON.parse(process.env.HTTPS) ? "https:" : "http:";
const host = process.env.REACT_APP_PROXY_HOST
const port = process.env.REACT_APP_PROXY_PORT
module.exports = function(app) {
app.use(
'/rest',
createProxyMiddleware({
target: {
protocol: protocol,
host: host,
port: port,
pfx: fs.readFileSync('src/root-cert.pem')
},
changeOrigin: true,
})
);
};
//// file: <project_root>/.env
HTTPS=true
REACT_APP_PROXY_HOST=localhost
REACT_APP_PROXY_PORT=6700
In this case instead of providing the target as a string, it should be given as an object containing protocol
, host
, port
and an attribute pfx
, which contains the certificate to validate the server via https.
In this case it is a hardcoded path within the project source directory, however it could also be set using environment variables.
The setting HTTPS=true
overwrites the default development setup and will by default start the development server at https://localhost:3000
.
With this setting as well as providing the correct certificate the server running on https can be reached without issues.
For reference, this solution is officially linked in the documentation of http-proxy-middleware
and the underlying node-http-proxy
:
This question also got some attention at other places, e.g.
Hope to help someone searching for the same problem, if there are any updates to this or things change feel free to add suggestions in the comments.
It will automatically read from HTTPS_PROXY
or HTTP_PROXY
so you dont need to do that.
From the docs:
A proxy to use for outgoing https requests. If the HTTPS_PROXY or https_proxy or HTTP_PROXY or http_proxy environment variables are set, proxy settings will be honored by the underlying request library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With