ZetCode

Go HTTP static files

last modified April 11, 2024

In this article we show how to set up HTTP servers in Go to serve static files.

$ go version
go version go1.22.2 linux/amd64

We use Go version 1.22.2.

The Hypertext Transfer Protocol (HTTP) is an application protocol for distributed, collaborative, hypermedia information systems. HTTP protocol is the foundation of data communication for the World Wide Web.

The net/http package provides HTTP client and server implementations and is used to create GET and POST requests.

Static files are files that do not change. They include CSS files, JavaScript files and images; also plain HTML files which do not contain template directives.

The http.FileServer is used to serve static files. It returns a handler that serves HTTP requests with the contents of the file system.

Serving static files

In the first example, we serve HTML files which include an image and a CSS file.

go.mod
main.go
public
├── about.html
├── css
│   └── format.css
├── img
│   └── sid.png
└── index.html

This is the project structure.

public/about.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/format.css">
    <title>About</title>
</head>
<body>

    <h2>About page</h2>

    <p>
        <a href="/">Home page</a>
    </p>
    
</body>
</html>

This is the about.html file.

public/index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/format.css">
    <title>Home page</title>
</head>

<body>

    <h2>Home page</h2>

    <p>
        <a href="about.html">About page</a>
    </p>

    <figure>
        <img src="img/sid.png" alt="Sid the sloth">
        <figcaption>Sid the sloth</figcaption>
    </figure>

</body>

</html>

This is the index.html page.

public/css/format.css
* {
    font-size: medium;
    background-color:#2c2b2b ;
    color: #e6d7d7;
}

This is the CSS file.

main.go
package main

import (
    "net/http"
)

func main() {

    fs := http.FileServer(http.Dir("./public"))
    http.Handle("/", fs)

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

We set up the server. The static files are read from the public directory.

Go serve image example

In the following example, we use template files to dynamically generate pages. Along the template system, we set up serving static files for the CSS file, that is included in the template file.

go.mod
main.go
public
└── css
    └── format.css
templates
└── layout.html

This is the project structure.

public/css/format.css
table {
    border-top: 1px solid #999;
    border-left: 1px solid #999;
    border-collapse: collapse;
}

td, th {
    padding: 5px;
    border-right: 1px solid #999;
    border-bottom: 1px solid #999;
}

tr:nth-child(2) {
    background-color: #c1f5f7;
}

We have some css code to style the HTML table.

templates/layout.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="public/css/format.css">
    <title>Users</title>
</head>

<body>

    <table>
        <thead>
            <tr>
                <th>User</th>
                <th>Occupation</th>
            </tr>
        </thead>

        <tbody>
            {{ range . }}
            <tr>
                <td>{{ .Name }}</td>
                <td>{{ .Occupation }}</td>
            </tr>
            {{ end }}
        </tbody>
    </table>

</body>

</html>

In the template file, we have directives which merge the passed data into the HTML table. The format.css file is included in the template and is served as a static resource.

main.go
package main

import (
    "html/template"
    "net/http"
    "os"
)

type User struct {
    Name       string
    Occupation string
}

func main() {

    fs := http.FileServer(http.Dir("public"))
    http.Handle("/public/", http.StripPrefix("/public/", fs))

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        tmpl := template.Must(template.ParseFiles("templates/layout.html"))

        data := []User{
            {Name: "John Doe", Occupation: "gardener"},
            {Name: "Roger Roe", Occupation: "driver"},
            {Name: "Thomas Green", Occupation: "teacher"},
        }

        tmpl.Execute(w, data)
    })

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

In the code example, we set up serving static files and the template engine.

fs := http.FileServer(http.Dir("public"))
http.Handle("/public/", http.StripPrefix("/public/", fs))

The static resources come from the public directory.

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

    tmpl := template.Must(template.ParseFiles("templates/layout.html"))

    data := []User{
        {Name: "John Doe", Occupation: "gardener"},
        {Name: "Roger Roe", Occupation: "driver"},
        {Name: "Thomas Green", Occupation: "teacher"},
    }

    tmpl.Execute(w, data)
})

Every resource that is not served from the public directory is managed with a template engine. In the anonymous function, we parse the layout.html file with template.parseFiles and merge it with the data.

Source

Go net/http package - reference

In this article we have showed how to work with static resources in Golang.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Go tutorials.