0

I am working on a Go Web Application with the following project structure:

  • ui
    • templates
      • login.tmpl
    • static
      • css
        • theme.css
  • main.go

My main.go code (only showing relevant parts for brevity). I am using chi router.

func main() {

    r := chi.NewRouter()

    var templates *template.Template
    templates = template.Must(template.ParseGlob("ui/templates/*.tmpl"))

    fileServer := http.FileServer(http.Dir("./ui/static/"))


    r.Handle("/static/", http.StripPrefix("/static/", fileServer))

    log.Fatal(http.ListenAndServe(":8080", r))
}

login.tmpl code for including css:

<head>
    <link rel="stylesheet" href="/static/css/theme.css">
</head>

Problem:

When this code runs, the html generates ok but the css is not applied to the page. In Chrome console, I see this error:

Refused to apply style from 'http://localhost:8080/static/css/theme.css' because its MIME type ('text/plain') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

codegeek
  • 32,236
  • 12
  • 63
  • 63
  • The error is pretty clear. What part do you need help with? – Jonathan Hall Sep 05 '19 at 20:13
  • sorry i don't understand the error. How to fix it ? do you mean the css file itself is corrupt? – codegeek Sep 05 '19 at 20:33
  • The error tells you that you're serving the CSS file with a content-type of "text/plain". This is wrong. It should be served with a content type of "text/css". – Jonathan Hall Sep 05 '19 at 20:37
  • @Flimzy but shouldn't the `FileServer` be setting the content type header automatically based on the file's extension or the first couple of bytes? – mkopriva Sep 05 '19 at 20:45
  • I did try the type="text/css" attribute but that did not change anything. – codegeek Sep 05 '19 at 20:45
  • 1
    Related/possible duplicate: https://stackoverflow.com/q/39520045/13860 – Jonathan Hall Sep 05 '19 at 20:50
  • @codegeek What is that `r` in your code? And where is the handler that is serving the login template? And how are you registering that handler? Is `r` perhaps a router that you've omitted from the code? Are you perhaps registering the template handler with the router, but then registering the fileserver with `http.Handle`? If so then that's your problem. `ListenAndServe` will pass all requests to `r`, and `http.Handle` will register all handlers to `http.DefaultServeMux`... so if `r` isn't `http.DefaultServeMux` then no request will ever reach your `fileServer`. – mkopriva Sep 06 '19 at 03:43
  • @mkopriva, thank you so much. I am using chi router library and yes, exactly right. I was making that mistake. But even with that change, still have the same issue though. Any other ideas ? i have edited the code above to show how r is being used. – codegeek Sep 06 '19 at 16:18
  • 1
    @codegeek can you show me what change you made? Is chi now serving the static files? How are you serving them? Did you follow their documentation? – mkopriva Sep 06 '19 at 16:19
  • 1
    @codegeek If I understand their example correctly you need to do `r.Handle("/static/*", ...`? Give it a try. https://github.com/go-chi/chi/blob/master/_examples/fileserver/main.go#L39 – mkopriva Sep 06 '19 at 16:27
  • omg, thank you so much. adding the * after /static/ fixed the issue. so instead of r.Handle("/static/",..), i changed it to r.Handle("/static/*",...). If you post this as your answer, I will accept it. – codegeek Sep 06 '19 at 16:30

1 Answers1

5

When using the chi router you have to use the * wildcard character at the end of the pattern to make the file server work.

r.Handle("/static/*", http.StripPrefix("/static/", fileServer))

https://github.com/go-chi/chi/blob/master/_examples/fileserver/main.go

mkopriva
  • 35,176
  • 4
  • 57
  • 71