Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

page not found - react/vite app not routing correctly on github pages

I deployed my app to gh-pages and the root works, but whenever I reroute or try and add to the root, I get a page not found error. Locally it works.

I've seen people suggest changing from <BrowserRouter> to <HashRouter> but that didn't help. I've also seen, and even used, a solution for create-react-app or webpack where you add some code to the index.html file in the public directory as well as a 404.html but the issue is vite has a different file structure.

Where would I put them in a vite application where there's nothing in the public directory. It does have a dist folder with an index.html but I'm not sure if that's the one.

Not sure what code I would need to show, but here's my main.jsx and App.jsx files:

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

function App() {
  return (
    <Router>
      <Header />
      <div className="app">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/example" element={<Example />} />
        </Routes>
      </div>
    </Router>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Again, locally this works, and when deploying to gh-pages the root or home page work, but no extended routes. Like I said, I had a similar issue with webpack but the solution I got there didn't work since vite has different file structure so I was unsure how to add the correct files.

EDIT: I've also seen a github issue where a user had a similar issue and the solution was to define routes in the vite.config.js but again the difference there is that user had multiple index.html files for each component/route. I just have the standard <BrowserRouter> situation wrapping my routes.

like image 625
Yehuda Avatar asked Sep 15 '25 22:09

Yehuda


2 Answers

adding a 404.html in the public folder:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Page Not Found</title>
    <script>
      sessionStorage.redirect = location.href;
    </script>
    <meta http-equiv="refresh" content="0;URL='/'" />
  </head>
  <body></body>
</html>

This JS in the root's index.html just before the closing </body> tag:

    <script>
      (() => {
        const redirect = sessionStorage.redirect;
        delete sessionStorage.redirect;
        if (redirect && redirect !== location.href) {
          history.replaceState(null, null, redirect);
        }
      })();
    </script>

And lastly reconfiguring the vite.config.js file:

export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, "index.html"),
        404: resolve(__dirname, "public/404.html"),
      },
    },
  },
});
like image 69
Yehuda Avatar answered Sep 19 '25 16:09

Yehuda


The main point here is to understand how GH pages serve static files. If there is not a file matched to a given URL, it automatically serves 404.html. So we just need to have 404.html, which has the same content as the index.html that we get from vite build.

Therefore, all you need to to is to copy index.html to 404.html inside dist directory.

I'm not sure how you manage GH page publish.

  • If you use Github Actions, please add a custom step to copy index.html to 404.html.

    cp ./dist/index.html ./dist/404.html
    
  • If you use gh-pages branch, I think you should copy index.html to 404.html before you push your changes to the branch.

I have created a public repo, which you can take a look for a reference. https://github.com/richard929/vite-gh-pages-example

I used react-router v6, and github actions for GH pages publish. I hope you already know about base configuration of vite, when deploying Vite app to static website.

like image 36
Richard Zhan Avatar answered Sep 19 '25 15:09

Richard Zhan