Search code examples
gofileserver

Serving HTML template and CSS on the same page with unconventional directory structure?


I have been trying to figure out how to serve css and html on the same page a few times now but I always just end up getting frustrated and using bootstrap. I really want to have my next project to have my own hand written css though. My source tree looks like this.

 - cmd
     - main.go 
 - static
     - css
     - templates

The reason my source tree looks like this because I want to have two packages in cmd: one for providing mock data the other for running the actual application. I have seen other posts where a http.FileServer is used however the project structure is much different with the main.go file at the root of the directory. I try to do a path something like:

fs := http.FileServer(http.Dir("../static/css"))
http.Handle("/signup/", http.StripPrefix("/static/css", fs))

Solution

  • As mentioned in the comment above the directory you place your files in will be relative to the compiled binary.

    go run main.go will compile in your current directory and then run the executable, therefore any paths in your application will be from the place your application was compiled not the overall project structure. I'll try and show an example below:

    // Current working directory
    /your-github-username/project-folder
    
    // Folder with entry point (main.go)
    /your-github-username/project-folder/cmd
    
    // Folder with static files (css file)
    /your-github-username/project-folder/static
    

    If you run go run ./cmd/main.go in your /your-github-username/project folder, then the way you have it written in your question your application will try to load static files from /your-github-username/static. I.e one folder up from where you ran the go run command from.

    But if you build and deploy your application, the /static folder will need to be re-created relative to wherever you put your compiled binary.

    Something nice to do in your main.go is to have some sort of initialisation function which checks for required folders, creates them and then outputs instructions if they are empty etc still need things put in them as part of your deployment process.

    If you want a really nice example of static file hosting I'd recommend looking at the go-chi router library examples as there are some great ones including a static file hosting one:

    go-chi static file example