diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 0000000..49bfe6d --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,10 @@ +import { PacmanLoader } from "react-spinners"; + +export function NotFound() { + return ( +
+ +

Not found.

+
+ ); +} diff --git a/src/router.tsx b/src/router.tsx index dbe489b..fcf97aa 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -1,5 +1,6 @@ import { Converter } from "./app/converter"; import { Home } from "./app/home"; +import { NotFound } from "./app/not-found"; import { Route, Routes } from "react-router"; export default function AppRouter() { @@ -7,6 +8,9 @@ export default function AppRouter() { } /> } /> + + {/* Fall back on app's 404 page. This is because of the SPA routing trick with 404.html used in GitHub Pages. */} + } /> ); } diff --git a/vite.config.ts b/vite.config.ts index 180abd0..27f5e72 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,8 @@ import tailwindcss from "@tailwindcss/vite"; import react from "@vitejs/plugin-react-swc"; +import fs from "fs"; import path from "path"; -import { defineConfig } from "vite"; +import { type Plugin, defineConfig } from "vite"; import sitemap from "vite-plugin-sitemap"; // https://vite.dev/config/ @@ -9,6 +10,7 @@ export default defineConfig({ plugins: [ react(), tailwindcss(), + copyIndexTo404(), sitemap({ hostname: "https://libresplit.org", dynamicRoutes: ["/converter"], @@ -25,3 +27,23 @@ export default defineConfig({ }, }, }); + +// Home spun plugin for copying index.html to 404.html at build time. +// This makes SPA routing work on GitHub pages. +function copyIndexTo404(): Plugin { + return { + name: "copy-index-to-404", + closeBundle() { + const distDir = path.resolve(__dirname, "dist"); + const indexPath = path.join(distDir, "index.html"); + const notFoundPath = path.join(distDir, "404.html"); + + if (fs.existsSync(indexPath)) { + fs.copyFileSync(indexPath, notFoundPath); + console.log("Copied index.html → 404.html for SPA fallback"); + } else { + console.warn("⚠️ index.html not found in dist directory"); + } + }, + }; +}