Why you should use a proxy server with Create React App
Tags: react
Published: 2022-03-30 15:16:32

**Written by [Joel Adewole](https://blog.logrocket.com/author/joeladewole/)✏️**

## Introduction

There are many cases in which developers need to consume APIs from the backend while using Create React App (CRA) to build an application. Because most client apps are hosted on different servers than the backend application, there are complications that arise as a result of requests being sent across both servers. CRA supports proxying to mitigate or entirely eliminate these issues.

In this article, we will discuss what a proxy server is, why you should use a proxy server in development, and uses cases for proxying requests in a React application. Then, we will implement a real life example of setting up a proxy server in React.

### Contents

*   [What is a proxy server?](#what-is-a-proxy-server)
*   [Why you should use a proxy server in development](#why-you-should-use-a-proxy-server-in-development)
*   [Use cases for proxying requests in a React application](#use-cases-for-proxying-requests-in-a-react-application)
*   [How to set up a proxy server in React](#how-to-set-up-a-proxy-server-in-react)
*   [Using a manually created proxy in Create React App](#using-a-manually-created-proxy-in-create-react-app)
*   [Conclusion](#conclusion)

## What is a proxy server?

A proxy server is a system or application that acts as a conduit between a client application and the server when it requests resources.

![Diagram of a proxy server](https://blog.logrocket.com/wp-content/uploads/2022/03/proxy-server-diagram.png)

The diagram above illustrates how proxy servers work. When you make a request to a server, it is routed through the proxy, which receives the response from the server and transmits the information back to the client.

## Why you should use a proxy server in development

You might be asking why it's necessary to route some requests through a proxy before sending them to the server. The following scenarios need the use of a proxy server:

Need to protect your client from cross-site attacks? Proxy servers add an extra degree of protection by allowing server responses to be validated before being delivered to the client. They can be used as web filters and firewalls.

To avoid crashes, bandwidth must be conserved and server traffic must be regulated. Proxy servers can cache requests and server responses so that not all queries are transmitted to the server at the same time. This is typically done when dealing with static information and huge files.

Proxy servers are useful when client data must be protected or a request must be made anonymously. Proxy servers do not provide information to the server, such as the client's location or IP address. Because the requests are not sent on a known network, this helps clients keep their data private by preventing hackers from intercepting important information.

Additionally, proxy servers can specify which requests are allowed and which are not. And finally, proxy servers can be used to log requests and the clients that make them within organizations that require it.

## Use cases for proxying requests in a React application

After understanding why proxy servers are required, it is critical to understand real-life scenarios in which proxy servers can be implemented. Some examples of proxying requests in React applications are listed below.

First is requesting HTTPS APIs in development (`https://localhost`). Browsers have cross-origin limitations that block HTTPS API requests from HTTP sites running on localhost. Proxy servers can assist in redirecting requests to APIs without having to go via the browser's default request options, which helps to evade several cross-origin limitations.

Second is fetching data from cross-origin APIs that don't support CORs in web browsers. Certain APIs, regardless of the Hypertext Transfer Protocol, don't support CORs for security concerns, and browsers impose same-origin policy to protect users from cross-site scripting (XSS). Proxy servers can be used to make API calls and then transmit the results to the web browser.

Finally, there is obtaining media resources from the server. A proxy server can be used to cache media files from the server, eliminating the need to send requests for such files to the server every time they are needed.

## How to set up a proxy server in React

There are two common approaches of setting up proxy servers in React applications developed using CRA. We have the default CRA proxy option as well as the npm package [http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware).

*Please note that these methods are only effective in the development. I recommend following these guides to implement proxies in production:*
 
 *   *[How to implement proxy server in Express](https://blog.logrocket.com/how-a-proxy-server-works-in-node-js/)*
 *   *[How to use Nginx as a reverse proxy server](https://blog.logrocket.com/how-to-run-a-node-js-server-with-nginx/)*

First, we will set up the application with CRA so we can set up the proxy servers.

### Create React App setup

Make sure you have Node installed on your computer to use CRA. Then, in a new directory, start a terminal and run the following command:

```shell
npx create-react-app proxyclient && cd proxyclient
```

The command above will create a new directory called `proxyclient` and set the terminal directory to `/proxyclient`. The following folders and files should be present in the folder:

![Proxyclient folder structure](https://blog.logrocket.com/wp-content/uploads/2022/03/proxyclient-folder-structure.png)

The `package.json` file should also have a similar structure:

```json
{
  "name": "proxyclient",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.3",
    "@testing-library/user-event": "^13.5.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
```

Edit the `App.js` file in the `src` folder to include the following code:

```js
import React, { useEffect } from 'react'
const App = () => {
  useEffect(() => {
    fetch('https://google.com/search?q=javascript')
      .then(resp => {
        console.log(resp);
        console.log('======success=======');
      })
      .catch(err => {
        console.log('======failure=======');
        console.log(err);
      });
  }, [])
  return (
    <div>App</div>
  )
}
export default App
```

Above, the `fetch` function is used to make a request to the cross-origin URL `https://google.com/search?q=javascript`.

The application server should then be started so that we can view the response. Run the following command in the project directory's terminal to start the application server:

<pre class="language-shell hljs">npm start
</pre>

By default, the above command will start listening on port 3000 on `localhost` or `127.0.0.1`. If you open a browser and type “localhost:3000,” you should see something like this in the console:

![error message](https://blog.logrocket.com/wp-content/uploads/2022/03/error-message.png)

### Using a CRA default proxy

To avoid this problem, we'll define our CRA's default proxy by including a `proxy` field in the `package.json` file like to this:

```json
{
  ...,
  "proxy": "https://www.google.com",
  ...
}
```

Then, in the `App.js` file, change the fetch request like so:

```js
fetch('/search?q=proxy')
```

Above, we removed the origin and structure the request URL as if it were a same-origin request. The request should be successful, as shown in the browser console. It should output something like this:

![success message](https://blog.logrocket.com/wp-content/uploads/2022/03/success-message.png)

Take notice of the URL in the response; it was transmitted to the browser as a same-origin, which resulted in `http://localhost:3000/search?q=proxy`, and the CORs error was gone. The browser receives the request and transmits it to the proxy server, which then redirects the request to the actual API server specified in the `package.json` file.

We may also make requests to several servers by specifying the routes that should be used to target a specific domain. To accomplish this, we'll structure our `proxy` field in the `package.json` file like so:

```json
{
  ...,
  "proxy": {
    "/search" : {
      "target" : "https://www.google.com",
      "changeOrigin" : true
    },
    "/jobs" : {
      "target" : "https://stackoverflow.com",
      "changeOrigin" : true
    }
  }
  ...
}
```

Above, we defined two `paths`: `/search` and `/jobs`, which target two separate domains.

When we execute a fetch request on `/jobs`, the browser sends the request as `http://localhost:3000/jobs`, but the proxy server forwards it as `https://stackoverflow.com/jobs`.

## Using a manually created proxy in Create React App

If you don't want to use the default CRA proxy, you may use the `http-proxy-middleware` npm package. Just note that this feature is available in `react-scripts@2.0.0` or higher.

This package must be installed as a project dependency before it can be used. To do so, open a terminal and execute the following command in the project directory:

```shell
npm i http-proxy-middleware --save
```

Ensure you don’t have proxy defined in the `package.json` file, then create a new file named `setupProxy.js` in the `src` directory. Add the following code snippet to the `setupProxy.js` file:

```js
const { createProxyMiddleware } = require('http-proxy-middleware');
const proxy = {
    target: 'https://www.google.com',
    changeOrigin: true
}
module.exports = function(app) {
  app.use(
    '/search',
    createProxyMiddleware(proxy)
  );
};
```

The code snippet above exports a function to the application so that the proxy middleware is registered to the application as soon as the development server starts up, without the need to import it into any file. Once the application is launched, it will start automatically.

We used `createProxyMiddleware` from `http-proxy-middleware` that we installed previously to register a proxy target for `/search`.

In cases when there are several proxy targets, we simply call the `app.use` function as follows:

```js
const { createProxyMiddleware } = require('http-proxy-middleware');
const proxy = {
    target: 'https://www.google.com',
    changeOrigin: true
}
const proxy2 = {
    target: 'https://www.stackoverflow.com',
    changeOrigin: true,
}
module.exports = function(app) {
  app.use(
    '/search',
    createProxyMiddleware(proxy)
  );

  app.use(
    '/jobs',
    createProxyMiddleware(proxy2)
  );
};
```

Above, we called the `app.use` method after creating another object named `proxy2` that included the proxy parameters of the other target domain in order to construct a proxy middleware.

## Conclusion

You may expect better security, confidential requests, regulated requests, and other benefits when you use proxy servers in your client applications. Now that you know why and how to use a dev proxy server with CRA, I encourage you to put it to use in your next project.

Please feel free to ask questions or make suggestions in the comments section below.

---

## Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket](https://www2.logrocket.com/react-performance-monitoring). 

![LogRocket signup](https://blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web and mobile apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free](https://www2.logrocket.com/react-performance-monitoring).