Documentation Index
Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
Use this file to discover all available pages before exploring further.
In this guide, you’ll create a simple web page with a layout and dynamic content. By the end, you’ll understand the core concepts of Mizu’s view system.
Prerequisites
- Go 1.22 or later installed
- Basic understanding of Go and HTML
- A text editor
Step 1: Create Your Project
First, create a new directory and initialize a Go module:
mkdir myapp && cd myapp
go mod init myapp
go get github.com/go-mizu/mizu
Step 2: Create the Directory Structure
The view package expects templates in a specific structure:
mkdir -p views/layouts views/pages
Your project should look like this:
myapp/
├── go.mod
├── go.sum
├── main.go (we'll create this)
└── views/
├── layouts/
│ └── default.html
└── pages/
├── home.html
└── about.html
Step 3: Create the Layout
A layout is the HTML shell that wraps your pages. Create views/layouts/default.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.Data.Title}}</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
nav {
background: #333;
color: white;
padding: 15px;
margin: -20px -20px 20px -20px;
}
nav a {
color: white;
text-decoration: none;
margin-right: 15px;
}
main {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
footer {
text-align: center;
margin-top: 20px;
color: #666;
}
</style>
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<main>
{{.Content}}
</main>
<footer>
Built with Mizu
</footer>
</body>
</html>
What’s happening here?
{{.Data.Title}} - Accesses the “Title” field from data you pass
{{.Content}} - This is where the page content gets inserted
- The layout provides the common structure (doctype, head, nav, footer)
Step 4: Create Pages
Pages are templates that provide the main content. Create views/pages/home.html:
<h1>Hello, {{.Data.Name}}!</h1>
<p>Welcome to our website. We're glad you're here.</p>
<h2>What We Offer</h2>
<ul>
{{range .Data.Features}}
<li>{{.}}</li>
{{end}}
</ul>
<button style="background: #2563eb; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer;">
Get Started
</button>
What’s happening here?
{{.Data.Name}} - Accesses data passed from your handler
{{range .Data.Features}}...{{end}} - Loops through a list
{{.}} - Inside range, this is the current item
- Page content is automatically inserted into the layout’s
{{.Content}}
Create views/pages/about.html:
<h1>About Us</h1>
<p>We are a team passionate about building great web applications with Go.</p>
<h2>Our Mission</h2>
<p>To make server-side rendering in Go simple, fast, and enjoyable.</p>
Step 5: Create the Go Application
Now create main.go:
package main
import (
"github.com/go-mizu/mizu"
"github.com/go-mizu/mizu/view"
)
func main() {
// Step 1: Create the view engine
engine := view.New(view.Config{
Dir: "./views", // Where templates are stored
Extension: ".html", // File extension to look for
Development: true, // Enable hot reload
})
// Step 2: Create the Mizu app
app := mizu.New()
// Step 3: Add the view middleware
// This makes the engine available to all handlers
app.Use(engine.Middleware())
// Step 4: Define routes
app.Get("/", homeHandler)
app.Get("/about", aboutHandler)
// Step 5: Start the server
app.Listen(":8080")
}
func homeHandler(c *mizu.Ctx) error {
return view.Render(c, "home", view.Data{
"Title": "Home - My App",
"Name": "Friend",
"Features": []string{
"Fast server-side rendering",
"Layout support",
"Development hot reload",
"Production caching",
},
})
}
func aboutHandler(c *mizu.Ctx) error {
return view.Render(c, "about", view.Data{
"Title": "About - My App",
})
}
What’s happening here?
- Create engine -
view.New() creates a view engine with your configuration
- Add middleware -
app.Use(engine.Middleware()) stores the engine in every request context
- Render pages -
view.Render(c, "home", data) renders the “home” page with data
Step 6: Run Your Application
Start the server:
Now open your browser to http://localhost:8080. You should see:
- The home page with your name and features list
- A styled button
- Navigation to the About page
Try editing views/pages/home.html and refreshing your browser - the changes appear instantly because Development mode is enabled!
Understanding the Data Flow
Here’s what happens when someone visits your site:
1. Browser requests http://localhost:8080/
|
v
2. Mizu routes to homeHandler
|
v
3. Handler calls view.Render(c, "home", data)
|
v
4. View engine finds views/pages/home.html
|
v
5. Engine also loads views/layouts/default.html
|
v
6. Page is rendered, output goes into layout's {{.Content}}
|
v
7. Final HTML sent to browser
Understanding Template Data
Templates receive a wrapper structure, not just your data directly:
// In your handler:
view.Render(c, "home", view.Data{
"Title": "Home",
"User": user,
})
<!-- In templates, access with .Data prefix: -->
<h1>{{.Data.Title}}</h1>
<p>{{.Data.User.Name}}</p>
<!-- The full structure: -->
<!-- .Page.Name = "home" (template name) -->
<!-- .Page.Layout = "default" (layout name) -->
<!-- .Data = your data map -->
<!-- .Content = rendered page (only in layouts) -->
Common Patterns
Using a Different Layout
Override the default layout for specific pages:
view.Render(c, "dashboard", data, view.Layout("admin"))
This uses views/layouts/admin.html instead of default.html.
Rendering Without a Layout
For partial HTML responses (AJAX, htmx, etc.):
view.Render(c, "user-row", data, view.NoLayout())
Using the Engine Directly
If you need the engine instance:
func handler(c *mizu.Ctx) error {
engine := view.From(c)
return engine.Render(c.Writer(), "home", data)
}
Next Steps
You’ve learned the basics! Here’s what to explore next:
- Engine - All configuration options explained
- Templates - Deep dive into Go template syntax
- Layouts - Advanced layout patterns
- Functions - Built-in and custom template functions
- Production - Embedding templates and caching for production
Troubleshooting
”template not found” Error
Check that:
- Your
views directory exists with layouts/ and pages/ subdirectories
- The file extension matches your Config (default is
.html)
- The name in
Render() matches the filename in pages/ (without extension)
Changes Not Appearing
Make sure Development: true is set in your view config. In production mode (the default), templates are cached.
”layout not found” Error
Make sure the layout file exists at views/layouts/default.html (or your custom DefaultLayout value).