# Deploying and Hosting a React App on an Apache Server

When I first started developing in React, I thought that — in order to host a React app — it was required that I had a VPS to install Node.js. Additionally, I had always associated Apache with PHP, believing that only PHP apps could be deployed on an [Apache server](https://httpd.apache.org/). However, now I realize that neither of these statements is true. In fact, it's entirely possible to deploy and host a React app on an Apache web server; it's even possible to do this on [shared hosting](https://en.wikipedia.org/wiki/Shared_web_hosting_service). This article aims to outline this process for you so that you don't fall into the same misconceptions that I did!

## Step #1: Creating a React App

First of all, you need a React app. If you already have one then you can skip this step.

To create a new React app, I am going to use [**Create React App**](https://github.com/facebookincubator/create-react-app).

> [Create React App](https://github.com/facebookincubator/create-react-app) is a comfortable environment for learning React, and is **the best way to start building a new** [**single-page**](https://reactjs.org/docs/glossary.html#single-page-application) **application in React**. — [_React documentation_](https://reactjs.org/docs/jsx-in-depth.html#children-in-jsx)

Install Create React App with the following command:

```shell
npm install -g create-react-app
```

Run this command to create a new React app called `my-app`_:_

```shell
npx create-react-app my-app
```

In the `my-app` folder you should now have the same files and folders displayed in the picture below:

![](https://writech.run/wp-content/uploads/2023/09/image.png)

You can now start coding and [developing your React app](https://dev.to/writech/the-top-3-react-ui-libraries-for-beginners-5fh6)!

The goal of this article is not to show you how to develop and build a React app. Rather, I will use a simple example of a three-page app from the [React Router official documentation](https://reactrouter.com/web/guides/quick-start).

```javascript
import React from "react";
import {
  BrowserRouter,
  Switch,
  Route,
  Link
} from "react-router-dom";

export default function App() {
  return (
    <BrowserRouter>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/users">Users</Link>
            </li>
          </ul>
        </nav>

        {/* A <Switch> looks through its children <Route>s and
            renders the first one that matches the current URL. */}
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}
```

## Step #2: Configuring package.json

To allow Create React App to produce a running build, add the following property to your `package.json` file:

```json
"homepage": "https://yourdomain.com"
```

As explained [here](https://create-react-app.dev/docs/deployment/#building-for-relative-paths), this will allow the Create React App to correctly infer which root path to use in the generated HTML file.

This is what the `package.json` file looks like:

```json
{
  "name": "my-app",
  "homepage": "https://antonellozanini.com",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.6",
    "@testing-library/react": "^11.2.2",
    "@testing-library/user-event": "^12.2.2",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.0",
    "web-vitals": "^0.2.4",
    "react-router-dom": "^5.2.0"
  },
  "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"
    ]
  }
}
```

## Step #3: Building the React App

Use this command to [build your React app](https://dev.to/writech/how-to-correctly-build-a-multi-environment-react-app-1hdg):

```shell
npm run build
```

As soon as the build process ends, a `build` folder will be created, ready to be deployed onto your Apache webserver.

Please note: **if your React app involves frontend routing this is not enough** as you need a `.htaccess` file. Create a `.htaccess` file and place it inside the `public` folder. This way, it will be automatically replicated into the `build` folder at the end of the build process.

Place the following line in your `.htaccess` file:

```shell
FallbackResource ./index.html
```

If users try to access a particular page directly without this configuration (for example `https://yourdomain.com/about`) a 404 error will be returned. This is because that URL does not map to anything in the file system of your server. `FallbackResource` ensures that `index.html` is loaded instead of allowing the frontend routing to be applied as expected.

## Step #4: Deploying the React App

Now, you are ready to deploy your app! Upload each file from your build folder into your domain's [Document Root](https://httpd.apache.org/docs/2.4/urlmapping.html#documentroot) folder. Any [FTP](https://en.wikipedia.org/wiki/File_Transfer_Protocol) client, like [Filezilla](https://filezilla-project.org/), will do. Et voilà!

![Home page [https://yourdomain.com/]](https://writech.run/wp-content/uploads/2023/09/image-1.png)

![About page [https://yourdomain.com/about]](https://writech.run/wp-content/uploads/2023/09/image-3.png)

![Users page [https://yourdomain.com/users]](https://writech.run/wp-content/uploads/2023/09/image-2.png)

## Bonus: Building for Relative Paths

If you want to **deploy your application to a subfolder** of your Document Root, you must follow these instructions**.** This also works for [subdomains created using Virtual Hosts](https://dev.to/writech/configuring-a-subdomain-in-apache2-22p8).

First, update the `homepage` property of your `package.json` file accordingly. Let's assume you want to deploy your React app to the _test_ subfolder, then your homepage property should be changed as follows:

```json
"homepage": "https://yourdomain.com/test"
```

This is what the `package.json` file would look like:

```json
{
  "name": "my-app",
  "homepage": "https://antonellozanini.com/test",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.6",
    "@testing-library/react": "^11.2.2",
    "@testing-library/user-event": "^12.2.2",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.0",
    "web-vitals": "^0.2.4",
    "react-router-dom": "^5.2.0"
  },
  "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"
    ]
  }
}
```

Then, you need to pass `"/test"` to the [`basename`](https://reactrouter.com/web/api/BrowserRouter/basename-string) prop in `<BrowserRouter>`. This way, **your app will be served from the specified subfolder**.

This is what `App.js` would look like:

```json
import React from "react";
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link
} from "react-router-dom";

export default function App() {
    return (
        <Router
            basename={"/test"}
        >
            <div>
                <nav>
                    <ul>
                        <li>
                            <Link to="/">Home</Link>
                        </li>
                        <li>
                            <Link to="/about">About</Link>
                        </li>
                        <li>
                            <Link to="/users">Users</Link>
                        </li>
                    </ul>
                </nav>

                {/* A <Switch> looks through its children <Route>s and
            renders the first one that matches the current URL. */}
                <Switch>
                    <Route path="/about">
                        <About />
                    </Route>
                    <Route path="/users">
                        <Users />
                    </Route>
                    <Route path="/">
                        <Home />
                    </Route>
                </Switch>
            </div>
        </Router>
    );
}

function Home() {
    return <h2>Home</h2>;
}

function About() {
    return <h2>About</h2>;
}

function Users() {
    return <h2>Users</h2>;
}
```

Now, you can follow steps 3 and 4 (from earlier on in this tutorial) and everything will work as expected!

You may also be interested in learning how to [deploy a React application on Dokku](https://dev.to/writech/how-to-deploy-a-react-application-on-dokku-3fbf).

## Conclusion

Node servers are not required to deploy and host React apps, as I have just shown. This can be achieved without any kind of degradation, and it will also help in maintaining frontend routing. The procedure is easy and can be replicated even on shared hosting (although this can be a bit tricky for relative paths).

Thanks for reading! I hope that you found this article helpful.

***
_The post "[Deploying and Hosting a React App on an Apache Server](https://dev.to/writech/deploying-and-hosting-a-react-app-on-an-apache-server-1d46/)" appeared first on [Writech](https://writech.run)._
