3

This is my Package.json

{
  "name": "man_power",
  "version": "0.1.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@ckeditor/ckeditor5-build-classic": "^35.4.0",
    "@ckeditor/ckeditor5-react": "^5.0.5",
    "@material-ui/core": "^4.12.4",
    "@tailwindcss/forms": "^0.5.2",
    "chart.js": "^3.8.0",
    "chartjs-adapter-moment": "^1.0.0",
    "moment": "^2.29.4",
    "react": "^18.2.0",
    "react-bootstrap": "^2.7.0",
    "react-dom": "^18.2.0",
    "react-flatpickr": "^3.10.13",
    "react-icons": "^4.7.1",
    "react-loading-skeleton": "^3.1.0",
    "react-router-dom": "^6.3.0",
    "react-select": "^5.7.0",
    "react-select-country-list": "^2.2.3",
    "react-transition-group": "^4.4.2",
    "validator": "^13.7.0",
    "sweetalert": "^2.1.2"
  },
  "devDependencies": {
    "@vitejs/plugin-react": "^2.0.0",
    "autoprefixer": "^10.4.7",
    "postcss": "^8.4.14",
    "tailwindcss": "^3.1.6",
    "vite": "^3.0.0"
  }
}

This is my vite.config.js:

import { defineConfig } from "vite";
import postcss from "./postcss.config.js";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  define: {
    "process.env": process.env,
  },
  css: {
    postcss,
  },
  plugins: [react()],
  resolve: {
    alias: [
      {
        find: /^~.+/,
        replacement: (val) => {
          return val.replace(/^~/, "");
        },
      },
    ],
  },
  build: {
    commonjsOptions: {
      transformMixedEsModules: true,
    },
  },
  server: {
    host: true,
  },
});

I am using

npm run build

it outputs dist folder which contains: enter image description here

I was trying to navigate to different pages with react-router-dom but when I refresh on a *domainName/dashboard * I get a 404 error on the server.

Check it out at:

https://manpower1.xpertsgroup.net/

6 Answers 6

3

The same issue brought me to this page. So, for any who may follow, the reason (quite obvious in hindsight) is explained here: https://create-react-app.dev/docs/deployment/#serving-apps-with-client-side-routing

To quote:

If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail. For example, if you used React Router with a route for /todos/42, the development server will respond to localhost:3000/todos/42 properly, but an Express serving a production build as above will not.

This is because when there is a fresh page load for a /todos/42, the server looks for the file build/todos/42 and does not find it. The server needs to be configured to respond to a request to /todos/42 by serving index.html. For example, we can amend our Express example above to serve index.html for any unknown paths: [...]

In my case (Apache server), I solved it by adding the following .htaccess file to my root folder:

Options -MultiViews
     RewriteEngine On
     RewriteCond %{REQUEST_FILENAME} !-f
     RewriteRule ^ index.html [QSA,L]

But solutions for other scenarios are discussed under the link.

Be aware, you may have to configure your server via your hosting provider to allow "RewriteEngine". In my case, the option was "mod_rewrite" (set to "on").

1
  • how can you fix this when running a vite app under docker. I cannot find anything that explains how it can be done
    – SpaceBison
    Commented Nov 6, 2023 at 17:22
3

I had the same issue and ended up solving it using this method:

SOLUTION: (nginx web servers)
Modify your nginx config file and add the following line:

location / {
    ...
    try_files $uri.html $uri $uri/ /index.html;
    ...
}

EXPLANATION:
When you build for production using Vite, there's only one index.html file inside your dist folder. It's neither React nor React-router-dom's fault since they know nothing about the server-side! They can only understand and operate in client-side.

So the thing that you need to do is to find your server's configuration file and manually redirect all routes to the root index.html

In my case, I had an nginx server running and I needed to directly modify nginx.conf (located in /etc/nginx/nginx.conf). But the hosting service didn't allow me to make any changes to server files. Finally, I found out that these services would give you some sort of way to modify some important files such as this one. There has to be a file named something_ngix.conf present in your /public folder (which after build process will be alongside your index.html) that will be picked up by them and overrides the nginx.conf on the server.

Check your hosting service provider documentation to see the exact file name and content. Then, make that tiny change I mentioned in the SOLUTION.

For instance, my nginx file name is liara_nginx.conf with the following content:

error_page 404 /404.html;
location / {
  index  index.html index.htm;
  try_files $uri.html $uri $uri/ /index.html;
}

location ~ /\.well-known {
  allow all;
}
1
  • Your solution is not relevant to the Vite configuration issue. Your response assumes there is an nginx serving the content.
    – mbenegas
    Commented May 5, 2023 at 3:39
2

If you are using vercel, you can use vercel rewrites.

Procedures:

  • make vercel.json file on root directory.

  • Add this code to vercel.json file :

     {
     "rewrites": [
       {
       "source": "/(.*)",
       "destination": "/"
       }
      ]
     }
    

EXPLANATION:

  • "source": "/(.*)" : This source pattern matches any URL, capturing all incoming requests.

  • "destination": "/": It specifies that regardless of the incoming URL, it should be rewritten to the root URL (/).

1

Create a _redirects file in the public folder and add the following line to it.

/*  /index.html  200

Works well with Netlify.

0

In the Apache server, in your .htaccess file add:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule> 
-2

I tried some things, specifically I asked some people in Discord React flux. I solved the issue by making a .htaccess file in Public folder.

It included the following code:

Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.html [QSA,L]

He also said if this didn't work try this code:

    <IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]
</IfModule> 

This was the explanation he gave:

the reason you get 404 is because the hosting server only knows about index.html. you reload on any other route then the react app isnt loaded so, on pretty mucll all hosting you have to follow this approach to make sure any 404 routes get redirected tot he index.html allowing react router to take control even with cra. If you build cra you end up with static assets to deploy, there's no difference 3xcept where you host. Some have the redirect setup, some don't.

I still need someone to explain me in detail.

Not the answer you're looking for? Browse other questions tagged or ask your own question.