> ## 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.

# Quick Start

> Create your first dynamic web page with Mizu's view engine in 5 minutes

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:

```bash theme={null}
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:

```bash theme={null}
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`:

```html theme={null}
<!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`:

```html theme={null}
<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`:

```html theme={null}
<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`:

```go theme={null}
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?**

1. **Create engine** - `view.New()` creates a view engine with your configuration
2. **Add middleware** - `app.Use(engine.Middleware())` stores the engine in every request context
3. **Render pages** - `view.Render(c, "home", data)` renders the "home" page with data

## Step 6: Run Your Application

Start the server:

```bash theme={null}
go run main.go
```

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:

```go theme={null}
// In your handler:
view.Render(c, "home", view.Data{
    "Title": "Home",
    "User":  user,
})
```

```html theme={null}
<!-- 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:

```go theme={null}
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.):

```go theme={null}
view.Render(c, "user-row", data, view.NoLayout())
```

### Using the Engine Directly

If you need the engine instance:

```go theme={null}
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](/view/engine)** - All configuration options explained
* **[Templates](/view/templates)** - Deep dive into Go template syntax
* **[Layouts](/view/layouts)** - Advanced layout patterns
* **[Functions](/view/functions)** - Built-in and custom template functions
* **[Production](/view/production)** - Embedding templates and caching for production

## Troubleshooting

### "template not found" Error

Check that:

1. Your `views` directory exists with `layouts/` and `pages/` subdirectories
2. The file extension matches your Config (default is `.html`)
3. 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).
