--- title: "Learning Go: Day Thirteen" date: 2024-05-15T08:00:00.0Z tags: - learning - go excerpt: "Creating some basic HTML output, and bundling static files" --- So now I want to start working on putting together a basic interface. This post won't be about creating the interface itself, but instead just the ground work that will allow me to build it over the next post or two. ## Creating some HTML output Alright, this was actually really straightforward. There's a module called [html/template](https://pkg.go.dev/html/template) that can be used to parse HTML, and includes a templating language. So I've created a super-simple HTML template at `templates/index.html`, and then use the `template.ParseFiles` function to parse and display it: ```html Oopsie

Oopsie uptime monitoring

``` ```go // main.go http.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) { pings := ping.ListGroupedBySite(db) if _, err := json.Marshal(pings); err != nil { w.Write([]byte(err.Error())) w.WriteHeader(http.StatusInternalServerError) return } else { w.Header().Set("Content-Type", "text/html") t, _ := template.ParseFiles("templates/index.html") t.Execute(w, nil) } }) ``` This works! But I can't deploy it, because when I compile the binary and upload it to my server it can't find the template files. Luckily, there's a package that can help me do that. ## Bundling static files This part is basically magic. I have no idea how it works, but there is a package called [embed](https://pkg.go.dev/embed). I can use it to create an instance of `FS` with some bundled static content, and that then gets bundled into my binary, and it takes about 3 lines of code to do it 🤯. ```go // main.go import ( "embed" ) //go:embed templates/* var content embed.FS http.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) { pings := ping.ListGroupedBySite(db) if _, err := json.Marshal(pings); err != nil { w.Write([]byte(err.Error())) w.WriteHeader(http.StatusInternalServerError) return } else { w.Header().Set("Content-Type", "text/html") t, _ := template.ParseFS(content, "templates/index.html") t.Execute(w, nil) } }) ``` And then when I run `go build`, the resulting binary file has the HTML bundled in it and I can run it on my server. This is a _really_ powerful thing to have built directly into the standard library. So that's it for today, like I mentioned earlier, my next one or two posts will mostly be focused on making a UI.