// backend\frontend.go package main import ( "embed" "fmt" "io/fs" "net/http" "path" "strings" ) // Vite-Build einbetten. // Beim Go-Build muss backend/web/dist bereits existieren. // //go:embed web/dist web/dist/* var embeddedFrontend embed.FS func makeFrontendHandler() (http.Handler, bool) { distFS, err := fs.Sub(embeddedFrontend, "web/dist") if err != nil { fmt.Println("⚠️ Frontend dist nicht im Binary gefunden – API läuft trotzdem:", err) return nil, false } // Prüfen, ob index.html vorhanden ist if _, err := fs.Stat(distFS, "index.html"); err != nil { fmt.Println("⚠️ Frontend index.html nicht im Binary gefunden – API läuft trotzdem:", err) return nil, false } fmt.Println("🖼️ Frontend dist: embedded web/dist") fileServer := http.FileServer(http.FS(distFS)) h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // /api bleibt API if strings.HasPrefix(r.URL.Path, "/api/") { http.NotFound(w, r) return } reqPath := r.URL.Path if reqPath == "" || reqPath == "/" { w.Header().Set("Cache-Control", "no-store") indexBytes, err := fs.ReadFile(distFS, "index.html") if err != nil { http.Error(w, "index.html nicht gefunden", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") _, _ = w.Write(indexBytes) return } // URL-Pfad bereinigen clean := path.Clean("/" + reqPath) rel := strings.TrimPrefix(clean, "/") // Wenn echte Datei im embedded FS existiert -> ausliefern if fi, err := fs.Stat(distFS, rel); err == nil && !fi.IsDir() { ext := strings.ToLower(path.Ext(rel)) if ext != "" && ext != ".html" { w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") } else { w.Header().Set("Cache-Control", "no-store") } fileServer.ServeHTTP(w, r) return } // SPA-Fallback w.Header().Set("Cache-Control", "no-store") indexBytes, err := fs.ReadFile(distFS, "index.html") if err != nil { http.Error(w, "index.html nicht gefunden", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") _, _ = w.Write(indexBytes) }) return h, true } func registerFrontend(mux *http.ServeMux) { h, ok := makeFrontendHandler() if !ok { return } mux.Handle("/", h) }