MERN Stack - Express and React on same port?

James Howell picture James Howell · May 29, 2018 · Viewed 14.5k times · Source

I'm working on a project with the MERN (MongoDB, Express, React, Node) stack and I'm having issues when posting data from a form within a React component to an API endpoint defined in Node.js. When I submit the form the browser just shows a CANNOT POST error. I'm pretty confident that if I create an event handler for the form submit within React and handle the POST using a library such as Axios that I could get around this issue.

But ultimately I believe this problem is because the Node backend is running on a different port to the React front end. Is there a way that I can configure my stack so I can use a standard form POST and potentially have the FE and BE running on the same port?

Answer

ovidb picture ovidb · May 30, 2018

I see that you are running an un-ejected CRA. That means that when you run npm run start from your create-react-app folder you should have react running on port 3000, the default port.

First I would recommend keeping your server and client code into a separate folder with separate package.json files

Now let suppose you have this code in /server/index.js Its straight out of the express example but the route starts with /api and also will run on port 5000. This is very important and you will see why in a minute.

const express = require('express');
const app = express();

app.get('/api/hello', (req, res) => res.send('Hello World!'))

app.listen(5000, () => console.log('Example app listening on port 5000!'))

Now back into your /client folder where I will assume your CRA is, open package.json and add the following lines:

"proxy": {
  "/api/*": {
    "target": "http://localhost:5000"
  }
},

Try now to do a call the server from react with axios for example:

const helloFromApi = 
  axios
    .get('/api/hello')
    .then(res => res.data);

Hope it helps

UPDATE 10/21/2019

proxy field in package.json must be a string

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