I'm using TanStack Router to create routes for my website, and everything works well when navigating through the application. However, I'm encountering a 404 error
when I refresh a route page or access it directly on GitHub Pages. The error message indicates File not found
.
Vite Configuration
//I have set the base URL in my vite.config.ts file to /portfolio:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';
import { TanStackRouterVite } from '@tanstack/router-plugin/vite';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), TanStackRouterVite()],
base: '/portfolio/',
});
File-Based Routes My project structure for routes is as follows:
- portfolio
- index.lazy.tsx
- about
- index.lazy.tsx
- etc...
GitHub Actions Deployment I deployed my app using the following deploy.yml configuration:
name: Deploy
on:
push:
branches:
- main
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
- name: Install dependencies
uses: bahmutov/npm-install@v1
- name: Build project
run: npm run build
- name: Upload production-ready build files
uses: actions/upload-artifact@v3
with:
name: production-files
path: ./dist
deploy:
name: Deploy
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: production-files
path: ./dist
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
[https://samir0ps.github.io/portfolio] [https://github.com/samir0ps/portfolio]
You can view my website here and the total code.
I configured my Vite project to use TanStack Router for routing, set the base URL in vite.config.ts
, and organized my routes using a file-based structure. Additionally, I created a GitHub Actions workflow (deploy.yml)
to automate the build and deployment process to GitHub Pages.
I expected the website to function correctly, including seamless routing through TanStack Router, even when refreshing a route page or accessing it directly on GitHub Pages. Specifically, I anticipated that my configuration and deployment setup would prevent 404 errors on page refresh, ensuring that all routes are correctly handled.
I fixed this error by creating 404.html file in the public folder which containes :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>React Router</title>
<script type="text/javascript">
// Number of path segments to keep in the URL
var pathSegmentsToKeep = 1;
// Get the current location object
var l = window.location;
// Rebuild the URL
var newUrl =
l.protocol + "//" + l.hostname + (l.port ? ":" + l.port : "") +
l.pathname.split("/").slice(0, 1 + pathSegmentsToKeep).join("/") +
"/?/" +
l.pathname.slice(1).split("/").slice(pathSegmentsToKeep).join("/").replace(/&/g, "~and~") +
(l.search ? "&" + l.search.slice(1).replace(/&/g, "~and~") : "") +
l.hash;
// Check if the current URL does not already match the new URL to avoid infinite redirect loop
if (l.href !== newUrl) {
l.replace(newUrl);
}
</script>
</head>
<body></body>
</html>
And I added a script to the index.html file of the application :
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="../portfolio/src/assets/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Portfolio</title>
<script type="text/javascript">
(function (l) {
if (l.search[1] === "/") {
var decoded = l.search
.slice(1)
.split("&")
.map(function (s) {
return s.replace(/~and~/g, "&");
})
.join("?");
window.history.replaceState(null, null, l.pathname.slice(0, -1) + decoded + l.hash);
}
})(window.location);
</script>
</head>
<body class=" bg-darkmain text-light">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
I hope this is helpful.