package ui import ( "embed" "fmt" "io/fs" "net/http" "strings" "github.com/gin-gonic/contrib/static" "github.com/gin-gonic/gin" ) //go:embed all:dist var staticFS embed.FS func AddRoutes(router gin.IRouter) { embeddedBuildFolder := newStaticFileSystem() fallbackFileSystem := newFallbackFileSystem(embeddedBuildFolder) router.Use(static.Serve("/", embeddedBuildFolder)) router.Use(static.Serve("/", fallbackFileSystem)) } type staticFileSystem struct { http.FileSystem } var _ static.ServeFileSystem = (*staticFileSystem)(nil) func newStaticFileSystem() *staticFileSystem { sub, err := fs.Sub(staticFS, "dist") if err != nil { panic(err) } return &staticFileSystem{ FileSystem: http.FS(sub), } } func (s *staticFileSystem) Exists(prefix string, path string) bool { buildpath := fmt.Sprintf("dist%s", path) if strings.HasSuffix(path, "/") { _, err := staticFS.ReadDir(strings.TrimSuffix(buildpath, "/")) return err == nil } f, err := staticFS.Open(buildpath) if f != nil { _ = f.Close() } return err == nil } type fallbackFileSystem struct { staticFileSystem *staticFileSystem } var _ static.ServeFileSystem = (*fallbackFileSystem)(nil) var _ http.FileSystem = (*fallbackFileSystem)(nil) func newFallbackFileSystem(staticFileSystem *staticFileSystem) *fallbackFileSystem { return &fallbackFileSystem{ staticFileSystem: staticFileSystem, } } func (f *fallbackFileSystem) Open(path string) (http.File, error) { return f.staticFileSystem.Open("/index.html") } func (f *fallbackFileSystem) Exists(prefix string, path string) bool { return true }