YPChen
Posted on March 30, 2024
The boilplate I begin with is the production of the tutorial by BugBytes on Youtube in the video: Golang + HTMX - Creating a Go webserver / HTMX Integration / Template Fragments. It’s really good and straightforward.
And I made these changes and will talk about them in this article:
- Instead of Booststrap, I used Tailwind CSS as the CSS library.
- I deployed the project on Zeabur, which is a personal preference (mainly because it’s free for the demo 😅). However, feel free to choose any similar service that suits your needs.
- I use go-chi for handling routes and to server static file(stylesheet).
- I utilized the Go embed directive for the serverless plan on Zeabur.
- Additionally, I explored htmx a bit more for reset inputs and animation."
The demo page: https://yp-go-htmx-simpleform.zeabur.app/
The repo: https://github.com/AlliesChen/go-htmx-simpleform/tree/main
DISCLAIMER: I’m not a GoLang expert, and I’m not yet a backend developer. However, I have experience in front-end development. Any suggestions to improve the structure of the demo or to correct any misunderstandings in this article would be greatly appreciated. 🙏
Go:embed for using files in serverless functions
To learn more about serverless functions, you can watch this video.
Serverless function cannot access the local file system of the server. Therefore, packing static files such as templates and stylesheets is necessary to serve them as part of the response.
As Zeabur is a platform that offers free hosting for serverless functions, the remaining challange will be how to include external files, such as templates or stylesheets, in the code package.
With go:embed
, a feature that enables embedding files into Go binaries, things couldn't be more easier.
Here is my file structure:
/static
|— output.css
/templates
|— index.html
main.go
Add the comments:
(PLEASE MAKE SURE NO SPACE BETWEEN THE TWO SLASH AND go:embed
or it won't work)
var (
//go:embed templates
templates embed.FS
//go:embed static
static embed.FS
pages = map[string]string{
"/": "templates/index.html",
"/add-film/": "templates/index.html",
}
)
In the handlers, rather than using template.ParseFiles
, we focus on the folders using template.ParseFS
with the page which is the path to the file includes the folder name.
// GET /
getPage := func(w http.ResponseWriter, r *http.Request) {
page, ok := pages[r.RequestURI]
// ...
tmpl, err := template.ParseFS(templates, page)
// ...
if err := tmpl.Execute(w, films); err != nil {
// ...
return
}
}
// POST /add-film
addFilm := func(w http.ResponseWriter, r *http.Request) {
page, ok := pages[r.RequestURI]
// ...
tmpl, err := template.ParseFS(templates, page)
// ...
if err := tmpl.ExecuteTemplate(w, "film-list-element", Film{
Title: title,
Director: director,
}); err != nil {
// ...
return
}
}
That's it. Execute go run main.go
and visit http://localhost:8000/ with your browser. There should be nothing different from BugBytes' production.
Include stylesheet built by Tailwind CSS
Similar to what we did for the HTML file in the templates directory, the serverless plan also requires embedding the stylesheet within the static folder, as previously accomplished.
In contrast to the earlier step, there is no need to parse the stylesheet. Instead, serve it directly when the website requests the /static path:
fileServer := http.FileServer(http.FS(static))
router.Handle("/static/*", fileServer)
This ensures that the stylesheet is readily available for use by the website without additional processing." 😊
Posted on March 30, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.