Sebi
Sebi

Reputation: 3979

Serve static files within GO using CHI Router

I'm using GO Web-App with CHI Router, but I'm unable to serve static files. This is my File Structure:

- cmd
 - main.go
 - assets
  - style.css
 - views
  - someView.templ

Now I want to serve all files within "assets" directory. But always get a 404 Not Found.

My very simple main.go:

func main() {

    router := chi.NewRouter()

    router.Get("/", indexHandler)
    router.Get("/showExternalProfile", showExternalProfileHandler)

    router.Post("/project_request", projectRequestHandler)
    router.Post("/downloadExternalProfile", downloadExternalProfileHandler)
    router.Post("/aigenerateProfile", aibeautifyHandler)
    router.Post("/project_clear", clearHandler)

    router.Handle("/assets/*", http.FileServer(http.Dir("./assets")))
    http.ListenAndServe(":8000", router)
}

Already tried different stuff, like "./assets" or "assets" in http.dir or /assets/* and /assets/ within Handle.

Does anyone have an idea?

Upvotes: 1

Views: 415

Answers (1)

Arun A S
Arun A S

Reputation: 7016

The chi repo has an example for this in the repo, you can find it here.

To apply it you your code, it would look like this

func main() {

    router := chi.NewRouter()

    router.Get("/", indexHandler)
    router.Get("/showExternalProfile", showExternalProfileHandler)

    router.Post("/project_request", projectRequestHandler)
    router.Post("/downloadExternalProfile", downloadExternalProfileHandler)
    router.Post("/aigenerateProfile", aibeautifyHandler)
    router.Post("/project_clear", clearHandler)


    // Create a route along /assets that will serve contents from
    // the ./assets/ folder.
    workDir, _ := os.Getwd()
    filesDir := http.Dir(filepath.Join(workDir, "assets"))
    FileServer(router, "/assets", filesDir)

    http.ListenAndServe(":8000", router)
}

// FileServer conveniently sets up a http.FileServer handler to serve
// static files from a http.FileSystem.
func FileServer(r chi.Router, path string, root http.FileSystem) {
    if strings.ContainsAny(path, "{}*") {
        panic("FileServer does not permit any URL parameters.")
    }

    if path != "/" && path[len(path)-1] != '/' {
        r.Get(path, http.RedirectHandler(path+"/", 301).ServeHTTP)
        path += "/"
    }
    path += "*"

    r.Get(path, func(w http.ResponseWriter, r *http.Request) {
        rctx := chi.RouteContext(r.Context())
        pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*")
        fs := http.StripPrefix(pathPrefix, http.FileServer(root))
        fs.ServeHTTP(w, r)
    })
}

As a personal opinion, if you are using any additional web servers such as nginx or apache, I would instead recommend to let them handle serving the static files. Or even better use a cdn, that way you no longer need to worry about static assets.

Upvotes: 0

Related Questions