29

I followed the Go Writing Web Applications tutorial but for whatever reason I am having trouble getting the app to serve CSS and JS. If I run my static page without the Go server the page CSS works fine. When I run the Go server on the other hand the CSS just doesn't work.

Here is what my HTML sort of looks like:

<link rel="stylesheet" href="../assets/css/bootstrap.min.css">
<link rel="stylesheet" href="../assets/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="../assets/css/custom.css">
        

then under the body tag:

<script src="../assets/js/jquery.min.js"></script>
<script src="../assets/js/bootstrap.min.js"></script>

My file tree looks like this:

go-affect/
├── data
│   └── …
├── static
│   ├── css
│   │   └── …
│   └── js
│   │   └── …
├── tmpl
│   ├── edit.html
│   ├── index.html
│   └── view.html
└── main.go

How do I get my Go application to serve the CSS and JavaScript I need?

EDIT:

The problem has since been solved, here is the working main:

func main() {
    http.HandleFunc("/view/", makeHandler(viewHandler))
    http.HandleFunc("/edit/", makeHandler(editHandler))
    http.HandleFunc("/save/", makeHandler(saveHandler))
    http.HandleFunc("/index/", makeHandler(indexHandler))

    
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

    http.ListenAndServe(":8080", nil)
}

Here is an example of the handlers I am using:

func indexHandler(w http.ResponseWriter, r *http.Request, title string) {
    p := &Page{Title: title}
    err := templates.ExecuteTemplate(w, "index.html", p)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}
Arun
  • 1,651
  • 4
  • 20
  • 31
bmacrevolution
  • 553
  • 2
  • 6
  • 14
  • Possible duplicate of [Include js file in Go template](http://stackoverflow.com/questions/28899675/include-js-file-in-go-template/28899786#28899786); and [With golang webserver where does the root of the website map onto the filesystem?](http://stackoverflow.com/questions/28745161/with-golang-webserver-where-does-the-root-of-the-website-map-onto-the-filesystem/28745280#28745280) – icza Apr 25 '17 at 06:53
  • Why is the link in html tag is "/assets/" but in the pic "/static/"? – Huy Ngo Oct 28 '18 at 13:42
  • Can I ask where you put your executable file? I'm having the same problem and I don't know how I should write the file path. – Huy Ngo Nov 03 '18 at 10:29
  • A Wonderful tutorial https://www.alexedwards.net/blog/serving-static-sites-with-go – Arun Feb 17 '20 at 06:46

2 Answers2

38
http.Handle("/", http.FileServer(http.Dir("css/")))

Would serve your css directory at /. Of course you can serve whichever directory at whatever path you choose.

You probably want to make sure that the static path isn't in the way of other paths and use something like this.

http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))

Placing both your js and css in the directory static in your project. This would then serve them at domain.com/static/css/filename.css and domain.com/static/js/filename.js

The StripPrefix method removes the prefix, so it doesn't try to search e.g. in the static directory for static/css/filename.css which, of course, it wouldn't find. It would look for css/filename.css in the static directory, which would be correct.

RayfenWindspear
  • 6,116
  • 1
  • 30
  • 42
  • 1
    Where should I place that line of code? In main with all the function handlers or in my function that serves the index template for example – bmacrevolution Apr 25 '17 at 04:08
  • Anytime. Usually before `http.ListenAndServe`. So probably in your main. – RayfenWindspear Apr 25 '17 at 04:09
  • Doing it that way does not seem to have worked. I posted some updated code – bmacrevolution Apr 25 '17 at 04:22
  • Use either the `/static/` path I added to my answer, or do one for each css and js, e.g. `http.Handle("/css/", http.FileServer(http.Dir("css/")))` and `http.Handle("/js/", http.FileServer(http.Dir("js/")))` – RayfenWindspear Apr 25 '17 at 04:25
  • You may need to use `http.StripPrefix` also to get the path right – John Weldon Apr 25 '17 at 04:26
  • @JohnWeldon I just realized that – RayfenWindspear Apr 25 '17 at 04:30
  • I tried replaced the http handle line with both http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("/static")))) and http.Handle("/static/", http.FileServer(http.Dir("static/"))) but still no luck. I also renamed the assets file to static so that the path names would be correct. My new screenshot reflects that change. I also added that line of code to the main function snippet above – bmacrevolution Apr 25 '17 at 04:35
  • 1
    Your code shows you are using `http.Dir("/static")`. Remove the `/`. Using it tells Go to look for the directory at the root of your filesystem. No `/` tells it to look relative to the go application. Admittedly... my example has the slash, so that's my bad (fixed) – RayfenWindspear Apr 25 '17 at 04:38
1

I added a link to my apache servers css dir into the head section of my template files. I keep the template and data files used by any go application under dir that the go application is running from. In this instance cgi-bin.

The template uses the css from my apache server assets/css directory :

<link rel="stylesheet" href="/assets/css/main.css" />

go apps run from my cgi-bin dir

sytle sheets are served from my apache assets/css dir