Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { PacmanLoader } from "react-spinners";

export function NotFound() {
return (
<div className="flex h-screen flex-col items-center justify-center space-y-4">
<PacmanLoader color="#2196f3" />
<p>Not found.</p>
</div>
);
}
4 changes: 4 additions & 0 deletions src/router.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
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() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/converter" element={<Converter />} />

{/* Fall back on app's 404 page. This is because of the SPA routing trick with 404.html used in GitHub Pages. */}
<Route path="*" element={<NotFound />} />
</Routes>
);
}
24 changes: 23 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
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/
export default defineConfig({
plugins: [
react(),
tailwindcss(),
copyIndexTo404(),
sitemap({
hostname: "https://libresplit.org",
dynamicRoutes: ["/converter"],
Expand All @@ -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");
}
},
};
}