Hosting React and a REST API with Express

TLDR- below is the code snippet for hosting a React Application and a Rest API on the same Express server.

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const path = require('path');
app.use(express.static(path.join(__dirname, 'build')));
app.use(bodyParser.json());
app.get('/api/getRequest', (req, res) => {
//API logic
});
});
app.post('/api/postRequest', (req, res) => {
//API logic
});
});
app.get('*', (req,res) => {
res.sendFile(path.join(__dirname, 'build/index.html'));
});
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log('Listening on port', port);
});

Serving up React

React applications need to be rendered on a server, and most React applications require an API. Express makes it easy to host both the React application and the application API.

First let’s assume that you have a React build (you can do this with the ‘npm run build’ command in create-react-app).

Next we will create our server script- before we get started be sure to install Express.

npm install express --save

To start off let’s import all of the tools we will need.

const express = require('express');       //Express to run our app
const app = express(); //Initiate the app
const bodyParser = require('body-parser');//Parse JSON requests
const path = require('path'); //Navigate to build folder

Now that we have our tools in place, let’s render the React application. The app.use() function along with path will reference the React build so it can be served by Express.

app.use(express.static(path.join(__dirname, 'build')));

Next let’s tell Express to send our React application to the client in the case that a request doesn’t match our specified API.

app.get('*', (req,res) => {
res.sendFile(path.join(__dirname, 'build/index.html'));
});

The finish off the React app, let’s initiate the Express server and have it start listening for requests.

const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log('Listening on port', port);
});

Now if you navigate to localhost:3000 you should see your react application.

We are only half way there- next let’s add a REST API to our Express app.

Adding the API

So far we’ve pulled our React build into express and served it up. Most React applications require an API to access databases and protect application functionality. Sometimes it’s best to keep your application and your API on the same server. Express does a lot of the heavy lifting here for us. Let’s get started by adding a get request to our API.

//API get request before serving React
app.get('/api/getRequest', (req, res) => {
//API logic
});
});
//Serving React
app.get('*', (req,res) => {
res.sendFile(path.join(__dirname, 'build/index.html'));
});

Here we’ve told our application to give a JSON response when a get request is received at the URL api/getRequest. Notice how we listed this API function before we listed the React build function. Express will run top to bottom when receiving a request and we want any request to be matched with the API requests before we serve up React.

Next let’s do the same with a post request.

//API get request before serving React
app.get('/api/getRequest', (req, res) => {
//API logic
});
});
//API post request also before serving React
app.post('/api/postRequest', (req, res) => {
//API logic
});
});
//Serving React
app.get('*', (req,res) => {
res.sendFile(path.join(__dirname, 'build/index.html'));
});

Once again we place the post request before the React build to ensure that the post API request is checked before defaulting to serving the React build.

Now that we have our API functions up, we can now ping our REST API from our React application. The final code snippet is found at the beginning of this post.

Thanks for reading!


If you’d like to hear more then subscribe to the weekly newsletter.