Serving static (css) files

Hello all,

Iā€™m new to Go but already exited, to practice I started to build a simple blog app, and everything is working smooth, except for the css.

I have been trying lotā€™s of examples for days now but it just keeps replying with a 404.
These are two of the examples Iā€™ve tried and both examples are explained on other resources in the same way:

http://www.alexedwards.net/blog/serving-static-sites-with-go

http://idealogylabs.com/blog/golang/2015/07/24/serving-static-files-with-golang-gorilla-mux.html

Iā€™ve tried both with and without Gorilla Mux, both examples fail as well as my own project down below. What is going wrong here?

Folder structure:

GolangTraining
    -blog
        -main
            -main.go
        -model
        -controller
        -static
            -style.css
        -view
            -post.html
        -templates
            -header.html

main.go:

package main

import (
	"net/http"
	"github.com/gorilla/mux"
	"github.com/jschalkwijk/GolangTraining/blog/model/home"
	"github.com/jschalkwijk/GolangTraining/blog/controller/posts"
	"github.com/jschalkwijk/GolangTraining/blog/controller/categories"
)

func main() {
	r := mux.NewRouter()
	// Index
	r.HandleFunc("/", home.DashboardHandler)
	// Posts
	r.HandleFunc("/posts/", posts.Index)
		p := r.PathPrefix("/posts").Subrouter()
		p.HandleFunc("/{id:[0-9]+}/{title}", posts.Single)
		//and some more subroutes
	// Categories
	r.HandleFunc("/categories/", categories.Index)
		c := r.PathPrefix("/categories").Subrouter()
		c.HandleFunc("/{id:[0-9]+}/{title}", categories.Single)
		//and some more subroutes

	r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))

	http.Handle("/", r)

	http.ListenAndServe(":8080", nil)

}

header.html:

{{define "header"}}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="/static/style.css" type="text/css" rel="stylesheet"/>
</head>
<body>
{{end}}

Thanks for helping out!

The problem is your code expects you to be in th directory above static/

How are you running this program? If you are using go run

  1. Please stop using go run, itā€™s a bad habit
  2. Go run always runs your program in a random temporary directory.

I recommend using go build or go install to build the program, then change into the correct directory before executing your program.

1 Like

Hello Dave,

I use the ā€œBuild main.go and runā€ function inside Webstorm. I have now builded it from the terminal and ran the exec, but still the browser canā€™t locate the file:
GET http://localhost:8080/static/style.css 404 (Not Found)

If I use the examples from the links itā€™s also the same using build and the run the exec.

Edit: Itā€™s not displaying anything at all at the moment. Just: open /Users/jschalkwijk/GolangTraining/blog/templates/header.html: no such file or directory
I do have a connection with my database and no errors in my terminal. But now it doesnā€™t seem to find the template files

Why not add a check on startup to ensure that the static files are where you expect them. Something like

_, err := os.Stat(filepath.Join(".", "static", "style.css"))

If err is not nil, exit the program and try to figure out why

2 Likes

Itā€™s saying that there is no such file or dir, but even if I put it the system path, it sayā€™s the same
panic: stat Users/jorn/Documents/Golang/src/github.com/jschalkwijk/GolangTraining/blog/static/style.css: no such file or directory

Iā€™m not a professional programmer yet so I donā€™t really know where to look now.

For anyone who wants to check out more of the code to maybe grasp the problem: https://github.com/jschalkwijk/GolangBlog

I think @dfc implied this but im not sure if it came across clearly, so Iā€™m gonna explicitly rephrase it:

It is critically important what directory youā€™re in when youā€™re starting your program.

In This tutorial the tutor phrased it:

Wherever you are in your directory structure when you [run your program], that becomes your root for your server.


For example:
Looking at this error

And this line in your code:

var templates, _ = filepath.Abs("../jschalkwijk/GolangTraining/blog/templates")

I would assume you were in ā€œ/Users/anydirectory/ā€ when you started your program (that time), which means ā€œ/Users/anydirectory/ā€ was the working directory for your program which according to the docs meant template was equal to /Users/jschalkwijk/GolangTraining/blog/templates which would probably lead nowhere useful.

I think Iā€™d need a full view of your console output to be more sure of this, but that might be a place to start looking.

2 Likes

This is a common stumbling block for web programming with Go.

When I first started learning web dev with Go, I also spent hours getting resources (css, js, images) to serve.

You can peruse this directory:

https://github.com/GoesToEleven/golang-webā€‹

It has working examples of CSS being served.

Specifically, this works:

https://github.com/GoesToEleven/golang-web/blob/master/025_solution/main.goā€‹

This is also a nice example which isnā€™t seen much in examples that are out there on the web:

https://github.com/GoesToEleven/golang-web/blob/master/023_http-server_FileServer/02/main.goā€‹

If this doesnā€™t help, send me the link to your code on github and Iā€™ll get it working.

1 Like

Always use absolute paths. Change them via a config file or environmental variables - e.g. os.Getenv("ASSET_DIR") - where ASSET_DIR is set to /Users/you/code/project/assets/ and not just ./assets/.

Relative paths to assets, configuration, etc. are a trap :smile:

1 Like

Thanks, after some trial and error I got it to work, and also have a better understanding of the how and why!

@dfc you where right, I just didnā€™t fully understand what you meant :slight_smile: @Jaytn Thanks for clarifying and the link to Toddā€™s lecture, this will help overcome future problems. And @toddmcleod as always thanks for your code base and quick reply, a lot of examples to work from!

I have had to change the path to:

r.PathPrefix("/GolangTraining/blog/static/css").Handler(http.StripPrefix("/GolangTraining/blog/static/css", http.FileServer(http.Dir("./GolangTraining/blog/static/css"))))

And the CSS path to:
<link href="/GolangTraining/blog/static/css/style.css" type="text/css" rel="stylesheet"/>

And then I changed directory into github.com/jschalkwijk and ran the main.go from there.

Thanks a lot!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.