Files
tiny-forge/internal/api/static.go
T
alexei.dolgolyov 5558396bb7 feat(docker-watcher): phase 11 - frontend embed & SSE
Embed SvelteKit static build in Go binary via go:embed. Event bus
for pub/sub with deploy log, instance status, and deploy status events.
SSE endpoints for real-time streaming. Frontend SSE client with
exponential backoff reconnection. Makefile for build pipeline.
Update Phase 12 auth plan with OAuth2/OIDC support.
2026-03-27 22:30:25 +03:00

43 lines
1.0 KiB
Go

package api
import (
"io/fs"
"net/http"
"strings"
)
// StaticHandler serves embedded SPA files with fallback to index.html
// for all non-API routes (SPA client-side routing support).
func StaticHandler(webFS fs.FS) http.Handler {
fileServer := http.FileServer(http.FS(webFS))
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Skip API routes — they are handled by the API router.
if strings.HasPrefix(r.URL.Path, "/api") {
http.NotFound(w, r)
return
}
// Try to serve the exact file.
path := strings.TrimPrefix(r.URL.Path, "/")
if path == "" {
path = "index.html"
}
// Check if file exists in the embedded FS.
f, err := webFS.Open(path)
if err == nil {
f.Close()
// Clear the JSON content-type set by middleware — let file server decide.
w.Header().Del("Content-Type")
fileServer.ServeHTTP(w, r)
return
}
// File not found: serve index.html for SPA client-side routing.
r.URL.Path = "/"
w.Header().Del("Content-Type")
fileServer.ServeHTTP(w, r)
})
}