How to configure pm2 serve command to serve multi-page React app?
Asked Answered
R

3

9

I created a ReactJS application using Create-React-App, and wanted to deploy it on a Linux server. I followed a tutorial that showed how to do so very simply by installing pm2 and serve, then after running the command:

npm run build

I ran the command that actually hosted the application:

pm2 serve build

Now the problem is whenever I visit a url that is not the base one, or click reload from browser while I'm on a page other than home page, I get 404 not found error.

I understand the previous command is meant to serve a single page only. My question is: is there a way to make the url for example http://myserver:port/a go to Route a in my app? Or at least go to http://myserver:port/ ?

I already have Nginx installed on the same server, as I am using it to host a Flask Python app, but I'm very new to all this and I am looking for a simple way that works, as I faced some difficulties to get the Python app hosted.

Please note that I am only using React, no Redux, express, or any Database, if that is of any relevance. I am also using BrowserRouter inside my app.

Rickrickard answered 29/8, 2018 at 12:50 Comment(0)
S
8

pm2 serve has a Single-Page-Application Mode (https://pm2.keymetrics.io/docs/usage/expose/#serving-spa-redirect-all-to-indexhtml)

From the docs:

To automatically redirect all queries to the index.html use the --spa option:

pm2 serve build --spa

Or if using ecosystem.config.js file:

module.exports = {
  script: "serve",
  env: {
    PM2_SERVE_PATH: 'build',
    PM2_SERVE_PORT: 8080,
    PM2_SERVE_SPA: 'true',
    PM2_SERVE_HOMEPAGE: '/index.html'
  }
}
Sonyasoo answered 6/1, 2020 at 6:41 Comment(3)
The --spa option indeed worked, but it caused my authentification to fail because requests that should give a 404 response (because the user isn't allowed to access that site) instead now return a 200 response (after successfully being redirected to the index page).Kinematograph
How are you determining if a user isn't allowed to access the site? If you have a backend server then probably use a static serve route to serve your app and an /api route to separate your requests.Sonyasoo
I managed to solve my problem by using a service worker, therefore I didn't dig too much into your solution. I have an /api route to my backend, but I wish to use multiple routes for my frontend. If I remember correctly, my issue was that if the user is not allowed to access specific routes, he is redirected to the /login page by my server. The --spa option redirects the /login to the index page, which I didn't want. I just wanted to comment the fact, that the --spa option may cause other issues in order to inform others.Kinematograph
I
6

I use Vue.js, "npm run build" command generates static files into dist folder, the pm2 command looks like this:

pm2 --name <appName> serve --spa <staticFolder> <port>
Imperative answered 15/2, 2021 at 17:5 Comment(1)
Worked for me on remote server.Enticement
O
1

pm2 serve build just serves build folder statically. So http://myserver:port/a will request file named 'a' in build folder. If it doesnt find it, it returns 404

To make ur server able to handle other routes, you cannot use pm2 serve. Instead you should start your flask server through pm2. You may take a look at How to run a python script like pm2 for nodejs

Orpha answered 29/8, 2018 at 14:26 Comment(2)
I don't get why use pm2 for Flask. The flask app is working properly as an API that the React app uses, while all my problems are related to the React app routing. I get you are saying what I want is not possible, so is there a workaround using pm2? Or a simple alternative to use altogether?Rickrickard
Oh the flask server is just an api server and it doesnt contain ur client react app? if so I would write a simple express server that serves the react app and handles routes for itOrpha

© 2022 - 2024 — McMap. All rights reserved.