17

I am trying to put my React app on the Heroku. The whole project include one API (express) and one client (ReactJS). I have put my API on heroku. But when I put my client on Heroku, it shows build succeeded. But when I open it, it shows Invalid Host header.

I google this problem and many people tell me to configure the HOST. But they are using webpack. I build this with create-react-app and I run it by npm start. I want to know how to solve this problem in most easy way. Thanks.

fourth
  • 599
  • 2
  • 5
  • 20

4 Answers4

29

If for any reason you were trying to deploy the client without the server, make sure to remove the:

"proxy": "http://localhost:5000"

from the package.json of the client..

Edit July 2019:

Create React App 2.0 has changed how we define Proxies. To determine which version you are using, check your client side package.json: "react-scripts" greater than "2.x.x"

Now in the client/ directory install this package:

npm install http-proxy-middleware --save

Create setupProxy.js file in client/src/ directory. There is no need to import this file anywhere, CRA looks for a file by this name and loads it.

There are different ways to add proxies:

Option 1:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    createProxyMiddleware(["/api", , "/otherApi"], { target: "http://localhost:5000" })
  );
};

Option 2

 const { createProxyMiddleware } = require('http-proxy-middleware');
     
    module.exports = function(app) {
        app.use(createProxyMiddleware('/api/**', { target: 'http://localhost:5000' }));
        app.use(createProxyMiddleware('/otherApi/**', { target: 'http://localhost:5000' }));
    };

Answering to comments

This proxy is just used in development environment. In production/Heroku everything runs under the same server, so there is not need for Proxy there.

create-react-app server just runs in Dev environment, so when the application is run in PROD mode, it is just used to generate the production JS bundle that will be served by the Node/Express server.

Check this other answer for questions on how to make it work in production.

Roberto Rodriguez
  • 3,179
  • 32
  • 31
  • But how do react send request to backend if you remove the proxy? You explicitly specify the path? – Kittichote Chain Jul 24 '19 at 14:17
  • @Kittichote Kamalapirat I updated my answer to answer your question. I hope it helps – Roberto Rodriguez Jul 24 '19 at 16:16
  • Thank you very much, @Roberto. What about if there is the server? For example, Node, React app? You're not supposed to use proxy for that right? Do you have to `run build` in client to create the static files for production? – Kittichote Chain Jul 25 '19 at 02:06
  • Proxies are used just in development mode, where React App is running in one port and Express server in other. In production mode normally everything will run under the same port. – Roberto Rodriguez Nov 04 '19 at 14:50
  • When I set the proxy URL to my heroku API server, I see "ECONNREFUSED" (No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host.) – s2t2 Dec 14 '19 at 18:36
  • When I follow the instructions above it works in my local dev environment but when deployed to heroku I see a 504 error in browser and in the heroku logs: [HPM] Error occurred while trying to proxy request /api/test-get?id=1 from basic-dm.herokuapp.com to http://localhost:5000 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors). I have verified that the API service is correctly responding by calling it directly with the heroku URL so it is up and running. So the proxy through react isn't working – dam Feb 13 '20 at 16:36
  • s2t2 and dam I updated my answer for you guys, I hope it helps. – Roberto Rodriguez Feb 13 '20 at 19:32
  • 1
    @RobertoRodriguez - you are my saviour. I have been fighting this for the past 3 days; Thank you The edit I would suggest is const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function(app) { app.use(createProxyMiddleware('/flask/**', { target: 'http://localhost:5000' })); }; – DataGuru Aug 14 '20 at 04:54
9

Invalid Host Header has been put in as a solution to DNS Rebinding.

To solve this, you have to create a file named .env.development in the create-react-app root folder. Inside this file, set

HOST=name.herokuapp.com

From the Documentation: https://create-react-app.dev/docs/proxying-api-requests-in-development/#invalid-host-header-errors-after-configuring-proxy

Agney
  • 18,522
  • 7
  • 57
  • 75
0

In my case, this was happening when I was running the React app in dev mode with webpack. I solved it by setting the value for allowedHosts in the webpack.config.js file. You can check out more about the allowedHosts property from the official webpack documentation.

For my case, I added the following code into module.exports of webpack.config.json:

module.exports = {
    // Some stuff that already exists before
    //.
    //.
    //.
    devServer: {
        allowedHosts: 'all'
    },
}

NOTE: It is not recommended that you use all for the allowedHosts property due to security issues. Be sure to specify specific hosts that the app must run on.

Suraj S Jain
  • 515
  • 3
  • 10
  • 24
0

In my case, the problem was caused by environment variables used in development, not being read in production because the .env file, containing the environment variables, was included in my .gitignore

To solve it, I added the environment variables to the Heroku host. From Heroku app: settings -> Congif Vars -> Reveal Config Vars

Then add the same environment variables you used in development, here. Once done, the error was gone!

environment variable being used in app

const accessToken = jwt.sign(
      { "userName": foundUser.userName },
      process.env.REACT_APP_ACCESS_TOKEN_SECRET,
      { expiresIn: '2h' },
);

const refreshToken = jwt.sign(
      { "userName": foundUser.userName },       
      process.env.REACT_APP_REFRESH_TOKEN_SECRET,
      { expiresIn: '1d' },
);

same environment variable in Heroku, Config Vars

  • Please do not post images of code, copy your code into the question with block code format: https://stackoverflow.com/help/how-to-ask – borchvm Mar 01 '23 at 10:35
  • @borchvm thanks for the heads up! Response has been updated without images of code. That said, the Heroku Config Vars image was left. Not sure of a better way to include it in the response, other than posting an image, and description. Lmk if there is a better way! – richard.seward May 01 '23 at 10:06