Deploy a Production React App to Vercel

In this tutorial, we will learn how to deploy a React app with a back-end API to Vercel. We will cover deploying Lambda Functions API to interact with the React front-end.

I have written two other tutorials where we will deploy the same app to Netlify and Heroku. (Links below)

[topads][/topads]

Let’s get started

Our React app will be very basic in nature, it calls Lambda Functions API with only one POST route and one GET route.

The GET route returns “Hello from Lambda Functions” and the POST route is just one field that when posting, it returns “I received your POST request. This is what you sent me: [from input]”.

The app also has client side routing with React Router that navigates to a secondary page and displays a 404 page when we enter a URL that does not exist.

Below you can see the demo app.

Demo App
Demo App

Upon loading, React calls the GET endpoint and displays a message. When submitting the single field form, React calls the POST endpoint and displays a message.

The React app was bootstrapped with Create React App (CRA), so the directory structure is pretty standard with the source files under the src directory and public assets under the public directory.

Deployment to Vercel

Vercel deploys your applications globally and puts them in front of CDNs. They also take care of your static assets component libraries and APIs. If using CI (Continuous Integration), Vercel only re-builds the part of your application that has changed.

You can head over to Vercel and create an account or log in.

Before starting, you will need to install Vercel CLI globally and then log in using the tool.

To install, type the following

npm i -g vercel

And to log in

vercel login

The tool will ask you to enter your email and then send you a confirmation

Vercel Login
Vercel Login

React with Lambda Functions

Take a look at the repo under the vercel-functions directory.

We have the React app right under the root directory and an api directory with our functions.

|-- /api
|-- /src
|-- ...

Lambda Functions

Under the api directory, we have two files: hello.js and world.js, each corresponding to a single lambda function. Both functions look pretty similar and the way Vercel distinguishes between a POST and a GET is the way they are called within React, with either a POST or GET request.

hello.js (GET)





world.js (POST)

module.exports = (req, res) => {
  res.send(
    `I received your POST request. This is what you sent me: ${req.body.post}`
  );
};

React App

This is how we call the API in our React app

...
  callApi = async () => {
    const response = await fetch('/api/hello');
    const body = await response.json();

    if (response.status !== 200) throw Error(body.message);

    return body;
  };

  handleSubmit = async e => {
    e.preventDefault();
    const response = await fetch('/api/world', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ post: this.state.post }),
    });
    const body = await response.text();

    this.setState({ responseToPost: body });
  };
...

To run the app locally, you will have to use the Vercel CLI as follows

vercel dev

When you run the command for the first time, Vercel will guide you through a series of steps. Follow them to link or create a new project on your Vercel dashboard. The command will also run your React app, so no need to start React with yarn or npm.

Deploying to Vercel

Now we are ready to deploy the app. All you have to do in your terminal is to type the following

vercel
Vercel CLI Deploy
Vercel CLI Deploy

After Vercel finishes deploying, it will give you a URL where you can preview the app. The Inspect URL will take you to the deployment overview on your dashboard.

Link to the deployed app: https://create-react-app-functions.esausilva.vercel.app/

Vercel is all about zero-configuration deployment, but if you are in need of some advanced configurations, take a look take a look at their docs.

[signupform][/signupform]

React with Express.js (Deprecated)

Take a look at the repo under the vercel-express directory.

As of April of this year, Vercel used to be called Zeit Now and with this re-branding they favor Functions over an Express.js app. Steps here are for historical purposes.

We have the React app right under the root directory and an api directory with the Express.js app.

|-- /api
|-- /src
|-- ...

Below is an extract from the Express.js code showing both routes.

app.get('/api/hello', (req, res) => {
  res.send({ express: 'Hello From Express' });
});

app.post('/api/world', (req, res) => {
  res.send(
    `I received your POST request. This is what you sent me: ${req.body.post}`,
  );
});

I decided to include client-side routing because Single Page Applications (SPAs) utilize the history API and when deployed, we need to include some “extra” steps. (Hint: we need to configure redirects)

Let’s say we deploy the app to demoapp.com. When we hit demoapp.com the app loads. Then we click “Another Page (demoapp.com/another-page)” menu link, and the page loads fine; but if we refresh the page we receive an error. That is because the server is looking for a file named “another-page”, but that file does not exist since our entire app (including routing) is being loaded from index.html. So somehow we need to tell the server to redirect all of the requests to index.html.

I will point that exact step in each of the deployments to correct this “issue”.

Required Configurations

If you fiddle through the Express.js code, you will notice it is set to start on port 5000, and if you have worked with CRA before, you know the React app will start on port 3000. So in order for React to call the API and not get a CORS issue, we will need to configure a proxy. Luckily for us the React team made it super easy to add a proxy to CRA.

Open package.json (under the root directory) and notice the below line

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

With this line we are telling CRA to proxy our API requests through port 5000.

The above proxy is only required for local development.

One more thing to note in package.json file is the following script

"now-build": "react-scripts build && mv build dist"

With this script, we are instructing Vercel to use react-scripts to build our React app for production and then rename the build directory to dist directory which Vercel identifies as the directory to serve.

One particular feature of Vercel is that it builds on the Vercel servers, instead of just pushing built code to their servers.

In order to deploy to Vercel, we need to create a configuration file named vercel.json at the root of the project. Let’s take a look at the contents of this file.

{
  "version": 2,
  "public": false,
  "builds": [
    { "src": "package.json", "use": "@now/static-build" },
    { "src": "/api/server.js", "use": "@now/node-server" }
  ],
  "routes": [
    { "src": "/api/.*", "dest": "/api/server.js" },
    { "src": "^/static/(.*)", "dest": "/static/$1" },
    { "src": ".*", "dest": "/index.html" }
  ]
}

Let’s break the file down:

In the first line we are telling Vercel to use version 2 of the Vercel platform and the name of the project. Line 2 is very important if you set it to true, then your source files will be publicly accessible, so set it to false if you don’t want that behavior.

Under the builds entry we are specifying how to run the React app and the Express.js app.

@now/static-build takes a package.json file, installs all of its dependencies and runs now-build npm script. In our case it will build the React app.

@now/node-server takes our Express.js app and wraps it inside a lambda. We also specify the path to the Express.js app.

Under the routes entry, we specify the different routing our setup will need. The first line we redirect calls coming from /api/* to Express.js. Second line serves the static files. And the third line is for client routing (i.e. React Router), which redirects everything to index.html.

If you want to know more configuration options, take a look at the docs.

Bonus

Instead of manual deployments, Vercel integrates very nicely with Git. They support GitHub, GitLab, and Bitbucket. (Docs)

References:

Conclusion

In this article, we learned how to deploy a React app with Lambda Functions API to Vercel. If you also read my other React Production tutorials, now you have the tools to deploy not only to Vercel but to Heroku and Netlify as well.

By learning how to deploy to multiple providers, you will be able to make an informed decision when it is time to deploy your project to production.

Thanks for reading this far. I hope you enjoyed the article and will share it on your social media accounts. You can connect with me on LinkedIn or on Twitter.


Originally Published on Bits and Pieces

[bottomads][/bottomads]

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.