Search code examples
gowebserversingle-page-application

Where is index.html in an embedded directory?


I am trying to embed a static site (and SPA) into my Go code. The high level structure of my project is

.
├── web.go
└── spa/
    └── index.html

My intent is to have http://localhost:8090/ serving index.html.

The relevant code to do that is

//go:embed spa
var spa embed.FS

log.Info("starting api server")
r := mux.NewRouter()
r.Handle("/", http.FileServer(http.FS(spa)))
log.Fatal(http.ListenAndServe(":8090", r))

When accessing http://localhost:8090/, I get

  • a directory listing page with a single link spa
  • upon clicking on this link I get a 404 page not found

How should I set this up?


Solution

  • With Gorilla Mux you need to specify a path prefix:

    package main
    
    import (
        "embed"
        "fmt"
        "github.com/gorilla/mux"
        "log"
        "net/http"
    )
    
    //go:embed spa
    var spa embed.FS
    
    func main() {
        log.Println("starting api server")
        r := mux.NewRouter()
        r.PathPrefix("/spa/").Handler(http.StripPrefix("/", http.FileServer(http.FS(spa))))
        log.Fatal(http.ListenAndServe(":8090", r))
    }
    

    This will route requests to <host>/spa/* to the handler. Then you must strip the prefix / as the contents of spa directory have the spa/ prefix without the leading /:

        b, _ := spa.ReadFile("spa/index.html")
        fmt.Println(string(b)) // file contents
    

    To wrap it up:

    http://localhost:8090/spa/index.html is routed to the r.PathPrefix("/spa/") handler. The route though is /spa/index.html, strip the first / resulting in spa/index.html and this finally matches the file path in the embedded variable.