1. Overview
In this tutorial, you’ll create a Go web server that uses
the
html/template
package to serve dynamic HTML pages, and leverages
Tailwind CSS
for styling. By the end, you'll have a clean, maintainable
approach for structuring your web application.
2. Project Structure
Here’s a simple, recommended file layout:
my-project/
├── go.mod
├── main.go
└── templates/
├── base.html
├── index.html
└── (other templates)
- go.mod holds your Go module info
(dependencies).
- main.go is your entry point, containing
func main()
.
- templates/ keeps your HTML files. You can
split them however you like.
3. Initialize Your Go Module
If you’re using modules (recommended for Go 1.13+), navigate to your folder and run:
cd my-project
go mod init github.com/yourusername/my-project
This creates a
go.mod
file tracking your dependencies.
4. Create Your HTML Templates
Tailwind can be included via a CDN link or by locally building the CSS. For simplicity, we’ll use a CDN. You can place the link in a base layout so all pages inherit it.
4.1 base.html (Layout)
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{block "title" .}}My Go App{{end}}</title>
<script href="https://unpkg.com/@tailwindcss/browser@4" rel="stylesheet"> </script>
</head>
<body class="bg-gray-900 text-gray-100 font-sans">
{{/* Navigation or header content goes here, if desired */}}
{{/* Where child templates inject their own content */}}
{{block "content" .}}{{end}}
{{/* A footer could also go here */}}
</body>
</html>
4.2 index.html (Child Template)
In the index.html
file, define the
title and content blocks
to override what’s in base.html
:
<!-- templates/index.html -->
{{define "title"}}Home Page{{end}}
{{define "content"}}
<div class="container mx-auto p-4">
<h1 class="text-2xl font-bold mb-4">Welcome to My Go + Tailwind Site!</h1>
<p class="leading-relaxed mb-4">
This page is styled with Tailwind CSS, served by a simple Go server.
</p>
<a href="/about" class="bg-teal-500 hover:bg-teal-400 text-white px-4 py-2 rounded">
About
</a>
</div>
{{end}}
Note how we use
Tailwind
classes (e.g.,
text-2xl
,
bg-teal-500
) in HTML for styling.
5. Write the Go Server (main.go)
Below is a minimal example that parses the templates and
serves
index.html
and a hypothetical
about.html
:
package main
import (
"fmt"
"html/template"
"log"
"net/http"
)
var tmpl *template.Template
func main() {
// Parse all .html files in the templates folder
var err error
tmpl, err = template.ParseGlob("templates/*.html")
if err != nil {
log.Fatalf("Error parsing templates: %v", err)
}
// Register routes
http.HandleFunc("/", indexHandler)
http.HandleFunc("/about", aboutHandler)
// Start server
fmt.Println("Server running on http://localhost:8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatalf("Server failed: %v", err)
}
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
// Render index.html (which uses base.html)
if err := tmpl.ExecuteTemplate(w, "index.html", nil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
// Suppose you also have about.html
if err := tmpl.ExecuteTemplate(w, "about.html", nil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
This setup ensures all HTML files in
templates/
are loaded at startup, letting you
reuse base.html
for consistent styling.
6. Tailwind: CDN vs. Local Build
The above example uses a CDN link for
Tailwind – the simplest approach. For advanced customization
(e.g., tailwind.config.js
), you can
build your own
Tailwind CSS and reference a local file. That process
typically involves:
-
Initializing Node in your project:
npm init -y
-
Installing dev dependencies:
npm install -D tailwindcss postcss autoprefixer
-
Creating a
tailwind.config.js
file, pointingcontent
to your HTML/Go files. -
Compiling your CSS with
npx tailwindcss -i ./input.css -o ./static/tailwind.css --watch
. -
Referencing
/static/tailwind.css
inbase.html
.
For most small apps, the **CDN** method is perfectly fine.
7. Testing Your Setup
1. Run
go run main.go
in your project root.
2. Visit
http://localhost:8080
in your browser.
3. You should see a page with the Tailwind styling (dark
background, large headings, etc.).
4. Navigate to /about
if you have an
about.html
page set up similarly.
8. FAQ
Q: Can I pass data to the templates?
A: Absolutely. Create a struct (e.g.,
type PageData struct
), fill it with data, and pass it as the final argument in
ExecuteTemplate
.
Q: Where do I put images or static files?
A: You can serve them from a
/static
directory. For example:
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
Then reference your static content via
/static/...
paths in your templates.
9. Summary
By following these steps, you’ve created a Go web server that uses HTML templates and Tailwind CSS. This setup keeps your code clean, your front-end styling powerful, and your build process straightforward. From here, you can:
-
Extend your templates with partials (e.g.,
header.html
,footer.html
) - Pass dynamic data into your pages
- Incorporate other tools like htmx or JavaScript frameworks if needed
With Tailwind’s utility classes, you can rapidly build responsive, modern UIs without manually writing much CSS. Enjoy your new Go + Tailwind stack!