skip to Main Content

I have a MERN app that I deployed on a shared hosting/cpanel. Now my server side works, but the react route doesn’t, when I try to visit a page, Ex. domain.com/about , it works as a get request on my server, instead of going to the about page. I used npm run build, and uploaded all the files from build folder to public_html. Then I clone the repository of my server side (client and server has different repo) to home/username/server.

Originally this is my file structure

client
    -src
    -package.json
    -etc
    -build (after npm run build)
server
    -app.js
    -models
    -routes
    -events
    -packagejson
    -etc

And I created a nodejs app on cpanel.
This is what I put on my node js app.

Application Mode : Product
Application Root : server
Application URL : domain.com
Application Startup file : app.js

Now it looks like this on my file manager

/home/username
    -public_html
         -index.html
         -other files from build folder
    -server
         -app.js
         -etc

Now I tried to add this apache configure to the existing .htaccess config (which contains passport config for nodejs)

RewriteEngine On
RewriteBase /
RewriteRule ^index.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]

With that, my react router works, but my server doesn’t. How can I make the server routes and react routes work at the same time? Sorry I’m new to this. Thank you!

2

Answers


  1. Chosen as BEST ANSWER

    I solved this by adding /api on my application url. My node js app looks like this:

    Application URL : domain.com/api
    

    Then I just added /api on my routes.


  2. I assume you configured your front-end application routing to use browser’s history API, so you’ll have "nice" URLs (without hash, exclamation mark, etc).

    Your problem comes from the fact, that now you have two applications competing for route resolution. One in front-end (in your case a React app), one in back-end (web server, usually Apache). Your back-end server needs to know when it should send to the client front-end application, which is bootstrapped from index.html file. So when the user refreshes the page (for example by hitting F5 on a keyboard), server will recognize that the URL which was requested, belongs to front-end app and will send this index.html file.

    You have two options to make it work:

    1. In React app, switch from history API "clean" URLs to "hashbang" style URLs, so your link will be for ex. domain.com/#!/about instead of domain.com/about – this solution does not require any changes in back-end configuration and it is simple (this works because anything after the # is resolved in the browser locally).

    2. Make back-end server aware which routes belong to front-end app, and always respond with index.html when there is a match – this require correct configuration and rules for web server route resolution, and will "cover" or "shadow" any back-end routes (or files) with front-end routes if there is a collision. You made an attempt with that, however it made rest of your back-end routes unusable. There are workarounds – for example: you could put your app in a subdirectory, to make configuration easier; or you could include all the front-end routes in htaccess; or you could catch 404 errors and then send index.html, then after particular route is still not found in your React app, then show 404 page. If you don’t know what you are doing, then I advise to stick to the first solution.

    More info:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search