Skip to content

Commit dbcd2da

Browse files
authored
Merge pull request #17 from LibreSplit/spa
Fix SPA routing on GitHub Pages
2 parents ae39c7c + 50c66b2 commit dbcd2da

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

src/app/not-found.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { PacmanLoader } from "react-spinners";
2+
3+
export function NotFound() {
4+
return (
5+
<div className="flex h-screen flex-col items-center justify-center space-y-4">
6+
<PacmanLoader color="#2196f3" />
7+
<p>Not found.</p>
8+
</div>
9+
);
10+
}

src/router.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { Converter } from "./app/converter";
22
import { Home } from "./app/home";
3+
import { NotFound } from "./app/not-found";
34
import { Route, Routes } from "react-router";
45

56
export default function AppRouter() {
67
return (
78
<Routes>
89
<Route path="/" element={<Home />} />
910
<Route path="/converter" element={<Converter />} />
11+
12+
{/* Fall back on app's 404 page. This is because of the SPA routing trick with 404.html used in GitHub Pages. */}
13+
<Route path="*" element={<NotFound />} />
1014
</Routes>
1115
);
1216
}

vite.config.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import tailwindcss from "@tailwindcss/vite";
22
import react from "@vitejs/plugin-react-swc";
3+
import fs from "fs";
34
import path from "path";
4-
import { defineConfig } from "vite";
5+
import { type Plugin, defineConfig } from "vite";
56
import sitemap from "vite-plugin-sitemap";
67

78
// https://vite.dev/config/
89
export default defineConfig({
910
plugins: [
1011
react(),
1112
tailwindcss(),
13+
copyIndexTo404(),
1214
sitemap({
1315
hostname: "https://libresplit.org",
1416
dynamicRoutes: ["/converter"],
@@ -25,3 +27,23 @@ export default defineConfig({
2527
},
2628
},
2729
});
30+
31+
// Home spun plugin for copying index.html to 404.html at build time.
32+
// This makes SPA routing work on GitHub pages.
33+
function copyIndexTo404(): Plugin {
34+
return {
35+
name: "copy-index-to-404",
36+
closeBundle() {
37+
const distDir = path.resolve(__dirname, "dist");
38+
const indexPath = path.join(distDir, "index.html");
39+
const notFoundPath = path.join(distDir, "404.html");
40+
41+
if (fs.existsSync(indexPath)) {
42+
fs.copyFileSync(indexPath, notFoundPath);
43+
console.log("Copied index.html → 404.html for SPA fallback");
44+
} else {
45+
console.warn("⚠️ index.html not found in dist directory");
46+
}
47+
},
48+
};
49+
}

0 commit comments

Comments
 (0)