package web import ( "embed" "io/fs" "net/http" "os" "path" ) //go:embed dist var assets embed.FS //go:embed index.html var Index embed.FS //go:embed 404.html var NotFound embed.FS // fsFunc is short-hand for constructing a http.FileSystem // implementation type fsFunc func(name string) (fs.File, error) func (f fsFunc) Open(name string) (fs.File, error) { return f(name) } // AssetsHandler returns an http.Handler that will serve files from // the Assets embed.FS. When locating a file, it will strip the given // prefix from the request and prepend the root to the filesystem // lookup: typical prefix might be /assets/, and root would be dist. func AssetsHandler(prefix, root string) http.Handler { handler := fsFunc(func(name string) (fs.File, error) { assetPath := path.Join(root, name) // If we can't find the asset, return the default index.html // content f, err := assets.Open(assetPath) if os.IsNotExist(err) { return NotFound.Open("404.html") } // Otherwise assume this is a legitimate request routed // correctly return f, err }) return http.StripPrefix(prefix, http.FileServer(http.FS(handler))) }