Skip to main content
The view engine is the core of Mizu’s template system. This guide covers all configuration options and how to use them effectively.

Creating an Engine

Create a view engine with view.New():

Configuration Options

Dir

The directory where your templates are stored.
The engine expects this structure inside the directory:

FS

An fs.FS filesystem to load templates from. Use this with embed.FS in production to bundle templates into your binary.
When FS is set, templates are loaded from the embedded filesystem instead of the local filesystem. The directory structure inside the embedded FS should match what you’d have on disk.

Extension

The file extension for template files.
You can use other extensions:

DefaultLayout

The layout template to use when rendering pages. This refers to a file in the layouts/ directory.
You can override this per-render with view.Layout() or disable it with view.NoLayout().

Delims

Custom template delimiters. Useful if your templates contain {{ and }} literally (common with Vue.js or Angular templates).
Now templates use <% %> instead:

Development

Enables development mode features:
  • Template reload - Templates are re-read from disk on every request
  • No caching - Templates are never cached
Important: Never enable Development mode in production. It significantly impacts performance. A common pattern is to use an environment variable:

Funcs

Custom template functions to add to all templates.
Now you can use these in templates:

Built-in Functions

The view engine provides these functions by default:

Engine Methods

New

Creates a new view engine with the given configuration.

Load

Loads and validates all templates at startup. Call this in production to fail fast if templates have errors.
This loads all files in layouts/ and pages/ directories.

Clear

Clears the template cache. Useful if you need to reload templates without restarting.

Render

Renders a page template. The first argument is an io.Writer (like http.ResponseWriter), followed by the template name, data, and optional render options.
The template name refers to a file in pages/ without the extension.

Middleware

Returns a Mizu middleware that adds the engine to every request context.
After adding this middleware, you can use view.From(c) and view.Render(c, ...) in handlers.

Package Functions

From

Retrieves the engine from a request context. Use this in handlers after adding the middleware.

Render (package-level)

A convenience function that gets the engine from context and renders. This is the most common way to render templates.
This is equivalent to:

Render Options

When calling Render(), you can pass options to customize behavior.

Layout

Override the default layout for this render:
This uses layouts/admin.html instead of the default layout.

NoLayout

Render without any layout (useful for partial responses):

Template Data Structure

When you render a template, your data is wrapped in a structure:
In page templates:
In layout templates:

Complete Example

Here’s a typical configuration for a production app:

Error Handling

Template Errors

The engine returns an Error type that wraps template parsing and execution errors:
The Error type has:
  • Kind - “page”, “layout”, or “template”
  • Name - Template name
  • Err - Underlying error (nil if not found)

ErrNotFound

Returned when a template file doesn’t exist:

Best Practices

1. Use Development Mode Locally

Always enable development mode during development:

2. Load Templates in Production

Call Load() at startup to catch template errors early:

3. Embed Templates for Production

Use embed.FS so templates are bundled in your binary:
This eliminates the need to deploy template files alongside your binary.

4. Keep Custom Functions Pure

Custom functions should be pure (no side effects):

5. Use Consistent Data Structures

Create struct types for complex template data:
Note: When using a struct instead of view.Data (which is map[string]any), access it directly in templates: