Run React and Node on single Port
As a beginner I was very confused on deployment MERN application with two different ports having separate backend (Node and Express) and Frontend (React). People often deploy their backend and frontend separately because of this issue.
In this article I will explain how we can make our app ready to be deployed on single hosting have both frontend and backend running on same Port.
Pre-requisites:
I will be creating MERN application from scratch, but I expect you to at least know basics of React.js and Node.js.
Let’s get Started
So, to get started we will first create a folder. You can name it anything, I am naming it as ‘website’.
Now open it in Visual Studio Code (or any other preferred IDE). Next open terminal and navigate to that folder.
Now we will create basic frontend and backend first so at least our app has some content. First, we will build our backend.
Building our backend
First, we will create a folder called backend. You can either create manually or through cli. For cli you can execute the below command
mkdir backend
It means make directory called backend.
Now navigate to that folder by the below command
cd backend
Next, we will initial our node app.
npm init -y
Next, we will install basic dependencies.
npm install express nodemon cors moment bcryptjs jsonwebtoken mongoose
Your folder will look like this after installing all dependencies.
Now we will create a file called server.js and paste the following code.
const express = require('express');const bodyParser = require('body-parser');const mongoose = require('mongoose');const cors = require('cors');const corsOptions = {origin: 'http://localhost:3000'}//init appconst app = express();//add corsapp.use(cors(corsOptions));//Setup server PORTconst port = process.env.PORT || 5000;// parse requests of content-type - application/x-www-form-urlencodedapp.use(bodyParser.urlencoded({ extended: true }));// parse requests of content-type - application/jsonapp.use(bodyParser.json());// Handle invalid OR 404 requestapp.use((_, res) => {res.status(404).json({success: false,message: "Invalid Request",});});
// Launch app to listen to specified portapp.listen(port, () => {console.log(`Voice app server is running on Port: ${port}`);});
I have placed comments in server.js if you do not understand anything.
Next, we will build basic structure of our backend folder. I will not be showing the basic structure creation process here. For that you can read my previous article that explains it in detail. https://abbasimusab2000.medium.com/best-node-js-express-js-based-project-structure-dbc8d8cf6153
You can clone the basic layout from GitHub so that you will save time.
https://github.com/MuqtadirBillah/node-express-basic-structure.git
Now, after cloning the above repo, your project will look like this
Now you will navigate to backend folder through terminal and install all dependencies via
npm install
Next, run the server using
npm start
If you can see this in console, it means your server is working perfectly.
Building Frontend
Next, we will create our frontend. We will not be creating complicated frontend. We will be just using default template.
To create frontend, we will open another terminal and again navigate to our main folder.
Now execute the below command
npx create-react-app frontend
If you can see this, it means frontend is created automatically.
Now let’s run our frontend to make sure it is installed properly.
If you can see this on “http://localhost:3000”, it means it is working perfectly.
Now, we will not make any changes, we will get to the main topic. running both frontend and backend on same port.
Running both Frontend & Backend
Now, first stop our frontend. To stop frontend go to terminal and press ctrl+c.
Next, we will create frontend build.
npm run build
Once, its built. You’ll see this on console.
Now, you can see a folder called “build” in your frontend folder.
Now, just copy and paste this build folder in your backend folder.
Now added I have added few lines in our server.js file. After adding these lines, your code will look like this.
const express = require("express");const app = express();const bodyParser = require("body-parser");var cors = require("cors");const mongooseConnection = require("./helpers/mongoose-connection");const appRoutes = require("./routes");const path = require("path");app.use(bodyParser.urlencoded());app.use(bodyParser.json());app.use(cors());app.use(express.static(path.join(__dirname,".","build")))app.use(express.static("public"));app.use("/api", appRoutes);app.use((req, res)=>{res.sendFile(path.join(__dirname,".","build","index.html"))})app.use((_, res) =>{res.send({message: 'Not found!'})});mongooseConnection();app.listen(5000, (req, res)=>{console.log("Server is listening on port 5000");})
Now, if you stop and restart your server from terminal and go to “http://localhost:5000”, you’ll see that frontend is running on it. It means you have both backend and frontend running on same path.
Now you know how to run both frontend and backend of your MERN application on same port.
Follow me for more interesting tips and tricks at Musab Abbasi — Medium
You can also find me on LinkedIn and Github