How to deploy React and Node app to Heroku

March 14, 2021
by Moiz Shaikh
  • Featured IImage

In our previous article, we implemented Infinite scroll in React and mongodb. We structured that project with our server files inside root directory, and our react files in a Separate client folder. We will use the same project and host both, the client and the node app on heroku. All in all, in this article, we will see how to deploy React and Node App to Heroku. You can find the project repository Here on my github.

Folder Structure

File Structure

File Structure

As you can see from the above image, we have our server files and a Client folder in the root directory. We don’t really need to make any changes in the client folder. But we will need to tweak the server files a little bit.

Inside the root directory, will create a file called Procfile and add the following line of code.

PROCFILE
web: node index.js

The Procfile basically tells Heroku App what it needs to do on startup.

The next thing we need to do, is to make some changes in our package.json file.
We will be adding a start script and a heroku-postbuild script. Along with these scripts, we will also add an engines property to specify the version of node we’re using.

Package.json
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "heroku-postbuild": "cd Client && npm install && npm run build",
    "start": "node index.js"
  },
  "author": "Moiz",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "mongoose": "^5.11.15"
  },
  "engines": {
    "node": "14.15.4"
  }
}

The post-build script will make heroku first navigate inside the Client folder, install all dependencies and then run the build process. Next, the start script to begin our node server. Finally we’ve added the engines property to specify the version of Node.js to be used.

Serve Build files

The last thing we need to do, is serve our static files using express.

Index.js
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const app = express();
const Games = require('./models/games');
const data = require('./data');
const path = require('path')

mongoose.connect(
  `mongodb+srv://${process.env.MONGO_USERNAME}:${process.env.MONGO_PASSWORD}@ihb-db.ql3nj.mongodb.net/Infinite-scroll-data?retryWrites=true&w=majority`,
  {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  }
);

let Connection = mongoose.connection;

Connection.once('open', async() => {
  console.log("Connected")
  const gamesExist = await Games.find({});
  if(gamesExist.length)
  return;
 
  Games.insertMany(data).then(res => {
    console.log(res)
  }).catch(err => console.log(err))
})

Connection.on('error', err => {
  console.error('connection error:',err)
})


app.use(express.json())
app.use(cors());

// ADD MIDDLEWARE TO SERVE ALL OUR STATIC BUILD FILES.
app.use(express.static(path.join(__dirname, 'Client', 'build')))

app.get('/game', async(req, res) => {
  const count = +req.query.count;
  const page = +req.query.page;
  try{
    const response = await Games.find().skip(count * (page - 1)).limit(count)
    res.status(200).json({games: response})
  }catch(err){
    console.log(err)
  }
})

// A CATCH ALL ROUTE TO SERVE OUR INDEX FILE IF THE PATH IS NOT MATCHED AGAINST EXISTING ROUTES
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname+'/Client/build/index.html'));
});


const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log("server is running")
})

In the above code, if you’ve noticed, we have also used the env variable to access our mongoDB username and password. We need to inform heroku about the environment variable we are using. There are two ways to do it. You can either add it using CLI or you can do it through settings, in your Heroku app’s dashboard. Let us create the Heroku app and add the config variables.

Creating Heroku App

You can create a Heroku app by simply running, heroku create my-app, or you can create one through the heroku Dasboard.

Next, we need to set the environment variables for our Heroku app. We can use the following command to set them.
heroku config:set MONGO_USERNAME='username'
heroku config:set MONGO_PASSWORD='password'

Alternatively, you can also set your config variables through Heroku Dashboard.

Config Variables on heroku

Heroku config

Pushing Code To Heroku

Now that we have everything in place, we just need to push this code to Heroku. You can run the following set of command to do so.

Steps
git init
heroku git:remote -a my-app
git add .
git commit -am "Upload to Heroku"
git push heroku main

When setting the remote, you can replace my-app with your app name.

So that’s all it takes to deploy React and Node app to Heroku. If you have any queries, feel free to drop a comment.

About

Full stack developer. Skilled in frontend technologies like React and Angular | Backend technologies like node and Express | SQL and NoSql Database. IoT hobbyist.

Get notified on our new articles

Subscribe to get the latest on Node.js, Angular, Blockchain and more. We never spam!
First Name:
Email:

Leave a Comment