fix: serve SvelteKit _app assets correctly
- Use all: prefix in go:embed to include _app/ directory (Go skips _-prefixed dirs by default) - Move jsonContentType middleware to /api route group only - Use http.ServeContent for proper MIME type detection - Remove unused fileServer variable
This commit is contained in:
@@ -88,9 +88,11 @@ func (s *Server) Router() chi.Router {
|
|||||||
r.Use(recovery)
|
r.Use(recovery)
|
||||||
r.Use(logging)
|
r.Use(logging)
|
||||||
r.Use(cors)
|
r.Use(cors)
|
||||||
r.Use(jsonContentType)
|
|
||||||
|
|
||||||
r.Route("/api", func(r chi.Router) {
|
r.Route("/api", func(r chi.Router) {
|
||||||
|
// JSON content type only for API routes (not static files).
|
||||||
|
r.Use(jsonContentType)
|
||||||
|
|
||||||
// Public auth endpoints (no auth required).
|
// Public auth endpoints (no auth required).
|
||||||
r.Post("/auth/login", s.login)
|
r.Post("/auth/login", s.login)
|
||||||
r.Get("/auth/oidc/login", s.oidcLogin)
|
r.Get("/auth/oidc/login", s.oidcLogin)
|
||||||
|
|||||||
+17
-12
@@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -9,8 +10,6 @@ import (
|
|||||||
// StaticHandler serves embedded SPA files with fallback to index.html
|
// StaticHandler serves embedded SPA files with fallback to index.html
|
||||||
// for all non-API routes (SPA client-side routing support).
|
// for all non-API routes (SPA client-side routing support).
|
||||||
func StaticHandler(webFS fs.FS) http.Handler {
|
func StaticHandler(webFS fs.FS) http.Handler {
|
||||||
fileServer := http.FileServer(http.FS(webFS))
|
|
||||||
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Skip API routes — they are handled by the API router.
|
// Skip API routes — they are handled by the API router.
|
||||||
if strings.HasPrefix(r.URL.Path, "/api") {
|
if strings.HasPrefix(r.URL.Path, "/api") {
|
||||||
@@ -18,25 +17,31 @@ func StaticHandler(webFS fs.FS) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to serve the exact file.
|
// Try to serve the exact file from the embedded FS.
|
||||||
path := strings.TrimPrefix(r.URL.Path, "/")
|
path := strings.TrimPrefix(r.URL.Path, "/")
|
||||||
if path == "" {
|
if path == "" {
|
||||||
path = "index.html"
|
path = "index.html"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if file exists in the embedded FS.
|
// Check if file exists in the embedded FS.
|
||||||
f, err := webFS.Open(path)
|
if f, err := webFS.Open(path); err == nil {
|
||||||
if err == nil {
|
stat, statErr := f.Stat()
|
||||||
f.Close()
|
f.Close()
|
||||||
// Clear the JSON content-type set by middleware — let file server decide.
|
if statErr == nil && !stat.IsDir() {
|
||||||
w.Header().Del("Content-Type")
|
// Serve the actual file. Use http.ServeContent for correct MIME detection.
|
||||||
fileServer.ServeHTTP(w, r)
|
file, _ := webFS.Open(path)
|
||||||
return
|
defer file.Close()
|
||||||
|
http.ServeContent(w, r, stat.Name(), stat.ModTime(), file.(io.ReadSeeker))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// File not found: serve index.html for SPA client-side routing.
|
// File not found: serve index.html for SPA client-side routing.
|
||||||
r.URL.Path = "/"
|
indexFile, _ := webFS.Open("index.html")
|
||||||
w.Header().Del("Content-Type")
|
if indexFile != nil {
|
||||||
fileServer.ServeHTTP(w, r)
|
defer indexFile.Close()
|
||||||
|
stat, _ := indexFile.Stat()
|
||||||
|
http.ServeContent(w, r, "index.html", stat.ModTime(), indexFile.(io.ReadSeeker))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ import "embed"
|
|||||||
// WebBuildFS holds the embedded SvelteKit static build output.
|
// WebBuildFS holds the embedded SvelteKit static build output.
|
||||||
// The build directory is populated by running `npm run build` in the web/ directory.
|
// The build directory is populated by running `npm run build` in the web/ directory.
|
||||||
//
|
//
|
||||||
//go:embed web/build
|
//go:embed all:web/build
|
||||||
var WebBuildFS embed.FS
|
var WebBuildFS embed.FS
|
||||||
|
|||||||
Reference in New Issue
Block a user