diff --git a/internal/server/server.go b/internal/server/server.go index 6a9f3ae..a1f6d01 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -94,8 +94,25 @@ func New(db *sql.DB, jwtSecret string, staticDir string) http.Handler { }) }) - // Serve static React app for all other routes - r.Handle("/*", http.FileServer(http.Dir(staticDir))) + // Serve static React app for all other routes, with SPA fallback + r.Handle("/*", spaHandler(staticDir)) return r } + +// spaHandler serves static files from dir, falling back to index.html for +// paths that don't match a file on disk (so client-side routing works). +func spaHandler(dir string) http.HandlerFunc { + fs := http.Dir(dir) + fileServer := http.FileServer(fs) + return func(w http.ResponseWriter, r *http.Request) { + // Try to open the requested path as a static file. + if f, err := fs.Open(r.URL.Path); err == nil { + f.Close() + fileServer.ServeHTTP(w, r) + return + } + // Not a real file — serve index.html and let React Router handle it. + http.ServeFile(w, r, dir+"/index.html") + } +}