Search code examples
reactjsnginxwebserverwebsite-deployment

"404 Not Found" on React website subfolders


I have a website at https://georgi.karapetrov.top/

Source code: https://github.com/GeorgiKarapetrov/georgi.karapetrov.top

The issue

The internal links to the different pages work. I can click on the "About" button in the top bar and the about page loads. In addition, I am routed to the URL for the "About" page.

However, the https://georgi.karapetrov.top/about URL does not load when opened directly.

The same is true for the rest. Accessing any "sub-folder" works by clicking a button but returns "404" not found when typing the URL in the address bar.

Unfortunatelly, nothing appears in the NgingX error log, when I try to access a subfolder. I don't know that I can route to sub-directory locations at the NginX level as these sub-folders don't actually exist on website path.

The website is a React App. The relevant code looks like this:

import React, { Suspense, lazy } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';

const { PUBLIC_URL } = 'https://georgi.karapetrov.top/';

const About = lazy(() => import('./pages/About'));

const App = () => (
  <BrowserRouter basename={PUBLIC_URL}>
    <Suspense fallback={<Main />}>
      <Switch>
        <Route exact path="/" component={Index} />
        <Route path="/about" component={About} />
        //etc
        <Route component={NotFound} status={404} />
      </Switch>
    </Suspense>
  </BrowserRouter>
);

export default App;

It works as intended when developing or serving a production build on local host, with npx serve -s build. It does not work when deployed to an NginX server.

How can I approach this issue?


Solution

  • I was wrong, the configuration is at the NginX level.

    The virtual host config "server" block used to read:

    server {
            #some config
            location / {
                    try_files $uri $uri/ =404;
            }
            #etc
    }
    

    Changing it solved the issue:

    server {
            #some config
            location / {
                    try_files $uri $uri/ /index.html;
            }
            error_page 404 =200 /index.html;
            #etc
    }
    

    Now all pages are routed as they should. Non-existing pages are sent to the custom 404 page.

    p.s. All the credit is to Ajeet Shah's original answer.