Requirements for the global *template.Template variable that Muxt uses to find route templates.
Muxt requires a package-level variable with type *template.Template:
package server
import (
"embed"
"html/template"
)
//go:embed *.gohtml
var templateFS embed.FS
var templates = template.Must(template.ParseFS(templateFS, "*.gohtml"))reference_template_embed_gen_decl.txt
| Requirement | Details |
|---|---|
| Scope | Package-level (not function-level) |
| Type | *template.Template |
| Initialization | Assignment expression (not const) |
| First argument | embed.FS variable when using ParseFS |
Package functions:
Template methods:
Single directory:
//go:embed *.gohtml
var fs embed.FS
var templates = template.Must(template.ParseFS(fs, "*.gohtml"))Nested directories:
//go:embed *.gohtml pages/*.gohtml components/*.gohtml
var fs embed.FS
var templates = template.Must(template.ParseFS(fs, "*.gohtml", "pages/*.gohtml", "components/*.gohtml"))reference_template_with_multiple_parsefs.txt
With custom functions:
var templates = template.Must(
template.New("").
Funcs(template.FuncMap{"add": func(a, b int) int { return a + b }}).
ParseFS(fs, "*.gohtml"),
)Different variable name:
muxt generate --use-templates-variable=myTemplatesvar myTemplates = template.Must(template.ParseFS(fs, "*.gohtml"))--use-templates-variable can be passed multiple times. Each variable becomes the root of an independent namespace.
muxt generate --use-templates-variable=adminTemplates --use-templates-variable=publicTemplates//go:embed admin/*.gohtml
var adminFS embed.FS
var adminTemplates = template.Must(template.ParseFS(adminFS, "admin/*.gohtml"))
//go:embed public/*.gohtml
var publicFS embed.FS
var publicTemplates = template.Must(template.ParseFS(publicFS, "public/*.gohtml"))Each generated handler calls ExecuteTemplate on its own variable, so each variable carries its own:
- Template name namespace —
{{define "header"}}inadminTemplatesdoes not collide with{{define "header"}}inpublicTemplates.*template.Templatehas a global namespace; later definitions silently overwrite earlier ones, so without separate variables every name in the app must be globally unique. Funcsmap — register admin-only template functions onadminTemplateswithout exposing them to public pages.- Template
Options — e.g.Option("missingkey=error")can apply to one set without forcing the same on the other. embed.FS— each variable can pull from a different filesystem, including filesystems exported by separate Go packages.
This is what makes templates portable across projects: a reusable admin component can ship its own template variable with its own names and helpers, and a consumer can mount it without worrying about name collisions in their own template set.
Routes from all variables are combined into a single generated TemplateRoutes function. Duplicate route patterns across variables are detected at generation time — if both adminTemplates and publicTemplates define GET /, generation fails with a duplicate route pattern error.
reference_multiple_templates_variables.txt err_duplicate_route_different_variables.txt
muxt check:
- Scans for
ExecuteTemplatecalls with string literals - Maps template names to data types
- Works without finding template variable
muxt generate:
- Finds template variable by name (
--use-templates-variableflag) - Parses embedded files to find route templates
- Generates handlers for templates matching route pattern
Variable not found:
- Ensure variable is package-level (not in function)
- Verify variable name matches
--use-templates-variableflag - Check variable type is
*template.Template
Templates not discovered:
- Verify
embed.FSvariable has correct//go:embeddirective - Ensure glob patterns in
ParseFSmatch your files - Check template names follow route syntax (see template-names.md)
If your configuration differs from these patterns, open an issue with your setup.