On this page
New / OptionsRuntime Metrics (expvars)Structured Logging (slog)Register / Has / ComponentsValidateAllRenderPageRenderFragmentString helpersDeprecated context aliasesRenderWithCollectorServeComponentServePageComponentMountWithDataMiddlewareRegisterFuncRegisterDirectiveMissing prop handlingComponentErrorHandlerParseFile / ComponentRendererRegistryDirective interfaceDirectiveBinding / ContextDirectiveRegistryDirectiveWithContentStyleCollectorScopeID / ScopeCSSError typesSentinel errorsCompileToTemplateRegisterTemplateTemplateTextGo API Reference
Complete reference for every exported symbol in the htmlc package. Import path: github.com/dhamidi/htmlc.
Creating an Engine
New
func New(opts Options) (*Engine, error)
Creates an Engine from opts. If opts.ComponentDir is set the directory is walked recursively and all *.vue files are registered before the engine is returned.
engine, err := htmlc.New(htmlc.Options{ ComponentDir: "./components", }) if err != nil { log.Fatal(err) }
Options
type Options struct { ComponentDir string Reload bool FS fs.FS Directives DirectiveRegistry Debug bool Logger *slog.Logger }
| Field | Description |
|---|---|
ComponentDir | Directory walked recursively for *.vue files. Each file is registered by its base name without extension (Button.vue → Button). When two files share the same base name the last one in lexical order wins. |
Reload | When true the engine checks the modification time of every registered file before each render and re-parses changed files automatically. Use during development; leave false in production. |
FS | When set, all file reads and directory walks use this fs.FS instead of the OS filesystem. ComponentDir is interpreted as a path within the FS. Useful with //go:embed. Hot-reload requires the FS to also implement fs.StatFS. |
Directives | Custom directives available to all components rendered by this engine. Keys are directive names without the v- prefix. Built-in directives cannot be overridden. |
Debug | When true the rendered HTML is annotated with HTML comments describing component boundaries, expression values, and slot contents. Development use only. |
Runtime Metrics (expvars)
PublishExpvars
func (e *Engine) PublishExpvars(prefix string) *Engine
Registers the engine's metrics in the global expvar registry under prefix. After calling this method all counters and configuration state are visible at the /debug/vars HTTP endpoint as a JSON object keyed by prefix. Returns the engine for method chaining.
Internally this creates a top-level *expvar.Map via expvar.NewMap(prefix). It panics if called twice with the same prefix — the same semantics as expvar.NewMap. Call it exactly once per engine per process, immediately after creating the engine.
engine, err := htmlc.New(htmlc.Options{ComponentDir: "./components"}) if err != nil { log.Fatal(err) } engine.PublishExpvars("myapp") // registers metrics under "myapp" key
Exposed variables
All variables appear as children of the prefix map in the /debug/vars JSON output:
| Key | Type | Description |
|---|---|---|
reload | expvar.Int (0/1) | Whether hot-reload is enabled. |
debug | expvar.Int (0/1) | Whether debug mode is enabled. |
componentDir | expvar.String | Current component directory path. |
fs | expvar.String | Type name of the current fs.FS, or "<nil>" when no custom FS is set. |
renders | expvar.Int | Cumulative number of successful render calls. |
renderErrors | expvar.Int | Cumulative number of failed render calls. |
reloads | expvar.Int | Cumulative number of hot-reload scans performed. |
renderNanos | expvar.Int | Cumulative render time in nanoseconds. |
components | expvar.Func → Int | Number of currently registered components (computed on each read). |
info.directives | expvar.Func → Array | Sorted list of registered custom directive names (computed on each read). |
Setter methods
These methods update both the live engine option and the corresponding expvar immediately. They are usable whether or not PublishExpvars has been called.
SetDebug
func (e *Engine) SetDebug(enabled bool)
Enables or disables debug mode. When enabled is true, rendered HTML is annotated with comments describing component boundaries, expression values, and slot contents. Updates the debug expvar to 1 or 0 immediately.
SetReload
func (e *Engine) SetReload(enabled bool)
Enables or disables hot-reload. When enabled is true, the engine stats every registered component file before each render and re-parses any that have changed. Updates the reload expvar to 1 or 0 immediately.
SetComponentDir
func (e *Engine) SetComponentDir(dir string) error
Changes the component directory to dir, walks the new directory recursively, and rebuilds the component registry. Returns an error if the directory cannot be walked. Updates the componentDir expvar to the new path immediately.
SetFS
func (e *Engine) SetFS(fsys fs.FS) error
Replaces the engine's filesystem with fsys, then rebuilds the component registry by walking the current ComponentDir inside the new FS. Returns an error if the directory walk fails. Updates the fs expvar to the type name of fsys (or "<nil>") immediately.
Integration note: The /debug/vars handler is registered on http.DefaultServeMux automatically when the expvar package is imported. For a custom *http.ServeMux, register it explicitly:
import "expvar" mux.Handle("GET /debug/vars", expvar.Handler())
Structured Logging (slog)
Options.Logger
type Options struct { // ... Logger *slog.Logger }
| Detail | Value |
|---|---|
| Type | *slog.Logger |
| Default | nil (no logging) |
| Effect when nil | A single pointer-nil check is performed per render; no allocations, no timing, behaviour identical to before structured logging was added. |
| Effect when non-nil | One structured log record is emitted for every component in the render tree. Records include component name, render duration, bytes written, and (on failure) the error. |
log/slog was added in Go 1.21. Passing a non-nil Logger requires Go 1.21 or later.Log record specification
Every rendered component emits one record. The attributes are:
| Attribute key | slog type | Value |
|---|---|---|
component | slog.String | Resolved component name (e.g. NavBar) |
duration | slog.Duration | Wall-clock time for the component subtree. Text handlers format this as 1.2ms; JSON handlers emit it as nanoseconds (int64). |
bytes | slog.Int64 | Bytes written by the component subtree. |
error | slog.Any | Non-nil only on LevelError records for failed renders. |
Example text-handler output:
time=2026-03-16T12:00:00.001Z level=DEBUG msg="component rendered" component=NavLink duration=1.2ms bytes=142 time=2026-03-16T12:00:00.002Z level=DEBUG msg="component rendered" component=NavBar duration=4.5ms bytes=612 time=2026-03-16T12:00:00.149Z level=DEBUG msg="component rendered" component=HomePage duration=148.6ms bytes=24576
Example JSON-handler output (note: duration is nanoseconds as int64):
{"time":"2026-03-16T12:00:00.001Z","level":"DEBUG","msg":"component rendered","component":"NavLink","duration":1200000,"bytes":142} {"time":"2026-03-16T12:00:00.149Z","level":"DEBUG","msg":"component rendered","component":"HomePage","duration":148600000,"bytes":24576}
Log levels
- Successful render — emitted at
slog.LevelDebugwith messagehtmlc.MsgComponentRendered. - Failed render — emitted at
slog.LevelErrorwith messagehtmlc.MsgComponentFailed, plus a non-nilerrorattribute.
Constants
const MsgComponentRendered = "component rendered" const MsgComponentFailed = "component render failed"
These constants are the stable message strings used in every log record. Reference them in log-based test assertions or alerting rules so that a future rename is caught at compile time rather than by a broken alert:
// Log assertion in a test: if record.Message != htmlc.MsgComponentRendered { t.Errorf("unexpected message: %q", record.Message) }
Renderer.WithLogger
func (r *Renderer) WithLogger(l *slog.Logger) *Renderer
Attaches l to the renderer. Use this when working with the low-level Renderer API directly — for example, to attach a request-scoped logger enriched with logger.With("request_id", id) to a per-request renderer. Returns r for method chaining.
renderer := htmlc.NewRenderer(component). WithComponents(reg). WithLogger(logger.With("request_id", requestID))
Record ordering
Records are emitted in leaf-first (post-order) order because the log call fires after the entire component subtree finishes rendering. The root page component is always the last record. This is useful for identifying which child component is the bottleneck: the first record with a high duration is where time is actually spent.
Performance
When Options.Logger is nil (the default), a single pointer-nil check is the only overhead per component. No timing, no allocations — behaviour is identical to before structured logging was added. Logging costs are incurred only when a non-nil logger is supplied.
Rendering
RenderPage
func (e *Engine) RenderPage(ctx context.Context, w io.Writer, pageName string, data map[string]any) error
Renders the named component as a full HTML page and writes the result to w. Scoped styles are collected from the entire component tree and injected as a <style> block immediately before the first </head> tag. If no </head> is found the style block is prepended to the output. The render is aborted and ctx.Err() is returned if the context is cancelled or its deadline is exceeded.
Use RenderPage for page components that include <!DOCTYPE html>, <html>, <head>, and <body>.
var buf bytes.Buffer err := engine.RenderPage(ctx, &buf, "HomePage", map[string]any{ "title": "Welcome", })
RenderFragment
func (e *Engine) RenderFragment(w io.Writer, name string, data map[string]any) error
Renders the named component as an HTML fragment and prepends the collected <style> block to the output. Does not search for a </head> tag. Use for partial page updates such as HTMX responses or turbo-frame updates.
String helpers
func (e *Engine) RenderPageString(ctx context.Context, name string, data map[string]any) (string, error) func (e *Engine) RenderFragmentString(ctx context.Context, name string, data map[string]any) (string, error)
Convenience wrappers around RenderPage and RenderFragment that return the result as a string instead of writing to an io.Writer.
Deprecated context aliases
// Deprecated: Use RenderPage, which now accepts a context.Context directly. func (e *Engine) RenderPageContext(ctx context.Context, w io.Writer, name string, data map[string]any) error // Deprecated: Use RenderFragment, which now accepts a context.Context directly. func (e *Engine) RenderFragmentContext(ctx context.Context, w io.Writer, name string, data map[string]any) error
RenderPageContext and RenderFragmentContext are deprecated aliases kept for backwards compatibility. RenderPage and RenderFragment now accept a context.Context directly as their first argument; use those instead.
RenderWithCollector
func (e *Engine) RenderWithCollector(ctx context.Context, name string, props map[string]any, collector *CustomElementCollector) (string, error)
Low-level render method that uses a caller-supplied CustomElementCollector. Most callers should use RenderPage or RenderFragment instead; those methods manage the collector lifecycle automatically. Use RenderWithCollector only when you need to control the collector lifecycle yourself — for example, when aggregating custom-element registrations across multiple renders before emitting scripts.
HTTP Integration
ServeComponent
func (e *Engine) ServeComponent(name string, data func(*http.Request) map[string]any) http.HandlerFunc
Returns an http.HandlerFunc that renders name as a fragment on every request. The data function is called per-request to build the template scope; it may be nil. Data middleware registered via WithDataMiddleware is applied after the data function. Sets Content-Type: text/html; charset=utf-8.
mux.HandleFunc("GET /search-results", engine.ServeComponent("SearchResults", func(r *http.Request) map[string]any { return map[string]any{"query": r.URL.Query().Get("q")} }))
ServePageComponent
func (e *Engine) ServePageComponent(name string, data func(*http.Request) (map[string]any, int)) http.HandlerFunc
Returns an http.HandlerFunc that renders name as a full HTML page. The data function returns both the template scope and the HTTP status code to send. A status code of 0 is treated as 200. If data is nil a 200 OK response with no template data is used.
mux.HandleFunc("GET /post/{id}", engine.ServePageComponent("PostPage", func(r *http.Request) (map[string]any, int) { post, err := db.GetPost(r.PathValue("id")) if err != nil { return map[string]any{"error": err.Error()}, http.StatusNotFound } return map[string]any{"post": post}, http.StatusOK }))
Mount
func (e *Engine) Mount(mux *http.ServeMux, routes map[string]string)
Registers multiple component routes on mux at once. Keys are http.ServeMux patterns (e.g. "GET /{$}", "GET /about"); values are component names. Each component is served as a full page via ServePageComponent with no data function.
engine.Mount(mux, map[string]string{ "GET /{$}": "HomePage", "GET /about": "AboutPage", "GET /blog": "BlogPage", })
WithDataMiddleware
func (e *Engine) WithDataMiddleware(fn func(*http.Request, map[string]any) map[string]any) *Engine
Adds a function that augments the data map on every HTTP-triggered render. Multiple middleware functions are called in registration order; later middleware can overwrite keys set by earlier ones. Returns the engine for chaining.
Data middleware applies only to the top-level render scope and is not automatically propagated into child component scopes. Pass shared values via RegisterFunc if child components need them.
engine.WithDataMiddleware(func(r *http.Request, data map[string]any) map[string]any { data["currentUser"] = userFromRequest(r) data["csrfToken"] = csrf.Token(r) return data })
Component Management
Register
func (e *Engine) Register(name, path string) error
Manually adds a component from path to the engine's registry under name, without requiring a directory scan. Useful for programmatically generated components or files outside ComponentDir.
Has
func (e *Engine) Has(name string) bool
Reports whether name is a registered component.
Components
func (e *Engine) Components() []string
Returns the names of all registered components in sorted order. Automatic lowercase aliases added by the engine are excluded.
ValidateAll
func (e *Engine) ValidateAll() []ValidationError
Checks every registered component for unresolvable child component references. Returns one ValidationError per problem; an empty slice means all components are valid. Call once at application startup to surface missing-component issues early.
if errs := engine.ValidateAll(); len(errs) != 0 { for _, e := range errs { log.Println(e) } os.Exit(1) }
Customization
RegisterFunc
func (e *Engine) RegisterFunc(name string, fn func(...any) (any, error)) *Engine
Adds a per-engine function available in all template expressions. The function is callable from templates as name(). Engine functions have lower priority than user-provided data keys. They are propagated automatically into every child component's scope. For behaviour attached to a Go type already in the render scope, exported methods are callable directly from expressions without registration — see Calling methods on scope values in the Concepts guide.
engine.RegisterFunc("formatDate", func(args ...any) (any, error) { t, ok := args[0].(time.Time) if !ok { return "", fmt.Errorf("formatDate: expected time.Time") } return t.Format("Jan 2, 2006"), nil })
RegisterDirective
func (e *Engine) RegisterDirective(name string, dir Directive)
Adds a custom directive under name (without the v- prefix). Replaces any previously registered directive with the same name. Panics if dir is nil.
engine.RegisterDirective("tooltip", &TooltipDirective{})
WithMissingPropHandler
func (e *Engine) WithMissingPropHandler(fn MissingPropFunc) *Engine
Sets the function called when any component has a missing prop. The default behaviour renders a visible [missing: <name>] placeholder. Use ErrorOnMissingProp for strict error behaviour or SubstituteMissingProp for legacy placeholder text.
// Abort rendering on any missing prop engine.WithMissingPropHandler(htmlc.ErrorOnMissingProp) // Substitute a legacy placeholder string engine.WithMissingPropHandler(htmlc.SubstituteMissingProp)
ComponentErrorHandler / HTMLErrorHandler
type ComponentErrorHandler func(w io.Writer, path []string, err error) error func HTMLErrorHandler() ComponentErrorHandler
ComponentErrorHandler is a function called when a child component fails to render. It receives the output writer, the component path (breadcrumb of component names from root to the failing component), and the error. It may write fallback HTML to w. If it returns a non-nil error, rendering is aborted; returning nil allows rendering to continue.
HTMLErrorHandler returns a built-in ComponentErrorHandler that writes an HTML comment describing the error and continues rendering, making component failures visible in the output without aborting the page.
renderer := htmlc.NewRenderer(component). WithComponents(reg). WithComponentErrorHandler(htmlc.HTMLErrorHandler())
Low-level API
ParseFile
func ParseFile(path, src string) (*Component, error)
Parses a .vue Single File Component from the string src. path is used only for error messages and the scope attribute hash. Returns a *Component whose Template field is a parsed HTML node tree. Only the top-level <template> and <style> sections are extracted; <template> is required. A <script> or <script setup> block causes ParseFile to return a parse error immediately.
Component
type Component struct { Template *html.Node // root of the parsed template node tree Script string // always empty; <script> blocks are rejected by ParseFile Style string // raw <style> content (empty if absent) Scoped bool // true when <style scoped> was present Path string // source file path passed to ParseFile Source string // raw source text (for error location reporting) Warnings []string // non-fatal issues found during parsing }
Holds the parsed representation of a .vue Single File Component. The Warnings field may contain notices about auto-corrected self-closing component tags.
Component.Props
func (c *Component) Props() []PropInfo
Walks the template AST and returns all top-level variable references the template uses. Identifiers starting with $ and v-for loop variables are excluded.
type PropInfo struct { Name string // identifier name Expressions []string // template expressions in which it appears }
Registry
type Registry map[string]*Component
Maps component names to their parsed components. Keys may be PascalCase or kebab-case. Most callers use Engine, which builds and maintains a Registry automatically.
Renderer
func NewRenderer(c *Component) *Renderer
Creates a Renderer for c. Use the builder methods below to configure it before calling Render.
Renderer is the low-level rendering primitive. Most callers should use Engine via RenderPage or RenderFragment. Use NewRenderer when you need fine-grained control over style collection or registry attachment.
| Builder method | Description |
|---|---|
WithStyles(sc *StyleCollector) *Renderer | Sets the StyleCollector that receives this component's style contribution. |
WithComponents(reg Registry) *Renderer | Attaches a component registry, enabling component composition. |
WithMissingPropHandler(fn MissingPropFunc) *Renderer | Sets the handler called when a template prop is absent from the scope. |
WithDirectives(dr DirectiveRegistry) *Renderer | Attaches a custom directive registry. |
WithContext(ctx context.Context) *Renderer | Attaches a context.Context; the render is aborted on cancellation. |
WithFuncs(funcs map[string]any) *Renderer | Attaches engine-registered functions so they are available in expressions and propagated to all child renderers. |
WithCollector(c *CustomElementCollector) *Renderer | Sets the CustomElementCollector used to accumulate custom-element registrations during rendering. |
WithComponentErrorHandler(h ComponentErrorHandler) *Renderer | Sets the handler called when a child component fails to render. See ComponentErrorHandler. |
WithComponentPath(path []string) *Renderer | Sets the component path (breadcrumb) passed to ComponentErrorHandler calls for nested components. |
WithNSComponents(ns map[string]map[string]*Component, componentDir string) *Renderer | Attaches a namespace-keyed component registry for multi-namespace component resolution. |
Renderer.Render / RenderString
func (r *Renderer) Render(w io.Writer, scope map[string]any) error func (r *Renderer) RenderString(scope map[string]any) (string, error)
Evaluates the component's template against scope and writes HTML to w (or returns it as a string). Prop validation and style collection happen here.
Package-level helpers
func Render(w io.Writer, c *Component, scope map[string]any) error func RenderString(c *Component, scope map[string]any) (string, error)
Convenience wrappers that create a temporary Renderer for c. They do not collect styles or support component composition. Use NewRenderer with WithStyles and WithComponents when those features are needed.
Directives
Directive interface
type Directive interface { Created(node *html.Node, binding DirectiveBinding, ctx DirectiveContext) error Mounted(w io.Writer, node *html.Node, binding DirectiveBinding, ctx DirectiveContext) error }
Implemented by custom directive types. Register with Engine.RegisterDirective or pass in Options.Directives. Only the Created and Mounted hooks are called because htmlc renders server-side.
Created— called before the element is rendered. Receives a shallow-cloned working node whoseAttrslice andDatafield may be freely mutated. Return a non-nil error to abort rendering.Mounted— called after the element's closing tag has been written tow. Bytes written towappear immediately after the element. Return a non-nil error to abort rendering.
DirectiveBinding / DirectiveContext
type DirectiveBinding struct { Value any // result of evaluating the directive expression RawExpr string // un-evaluated expression string from the template Arg string // directive argument after the colon, e.g. "href" in v-bind:href Modifiers map[string]bool // dot-separated modifiers, e.g. {"prevent": true} }
type DirectiveContext struct { Registry Registry // component registry the renderer is using RenderedChildHTML string // fully rendered inner HTML of the host element; empty for void elements }
RenderedChildHTML contains the fully rendered children of the directive's host element — all template expressions evaluated, child components expanded — before either hook runs. It is available in both Created and Mounted. Use it to inspect or transform the rendered subtree, for example in a syntax-highlighting directive that needs the source text after expression evaluation.
DirectiveRegistry
type DirectiveRegistry map[string]Directive
Maps directive names (without the v- prefix) to their implementations. Keys are lower-kebab-case; the renderer normalises names before lookup.
DirectiveWithContent
type DirectiveWithContent interface { Directive InnerHTML() (html string, ok bool) }
Optional extension of Directive. When a directive's Created hook wants to replace the element's children with custom HTML, implement this interface. The renderer calls InnerHTML after Created returns; if it returns a non-empty string, the element's template children are skipped and the returned HTML is written verbatim between the opening and closing tags (equivalent to v-html on the element itself). Return ("", false) to fall back to normal child rendering.
// Example: a directive that wraps children in a callout box type CalloutDirective struct { renderedHTML string } func (d *CalloutDirective) Created(node *html.Node, b htmlc.DirectiveBinding, ctx htmlc.DirectiveContext) error { d.renderedHTML = ctx.RenderedChildHTML return nil } func (d *CalloutDirective) Mounted(w io.Writer, node *html.Node, b htmlc.DirectiveBinding, ctx htmlc.DirectiveContext) error { return nil } func (d *CalloutDirective) InnerHTML() (string, bool) { h := d.renderedHTML d.renderedHTML = "" if h == "" { return "", false } return `<div class="callout">` + h + `</div>`, true }
Style Collection
StyleCollector
type StyleCollector struct { /* unexported fields */ }
Accumulates StyleContribution values from one or more component renders into a single ordered list, deduplicating contributions from the same scoped component. Engine creates and manages a StyleCollector automatically on each render call.
func (sc *StyleCollector) Add(c StyleContribution) func (sc *StyleCollector) All() []StyleContribution
Add— appendsc, skipping duplicates. Two contributions are duplicates when they share the same composite key (ScopeID + CSS).All— returns all contributions in the order they were added.
StyleContribution
type StyleContribution struct { ScopeID string // scope attribute name (e.g. "data-v-a1b2c3d4"), empty for global styles CSS string // stylesheet text, already rewritten by ScopeCSS for scoped components }
ScopeID / ScopeCSS
func ScopeID(path string) string func ScopeCSS(css, scopeAttr string) string
ScopeID— returns"data-v-"followed by 8 hex digits derived from the FNV-1a 32-bit hash ofpath.ScopeCSS— rewritescssso that every selector in every non-@-rule hasscopeAttrappended to its last compound selector.@-rules are passed through verbatim.
Error Handling
Error types
ParseError
type ParseError struct { Path string // source file path Msg string // human-readable description Location *SourceLocation // source position, or nil if unknown }
Returned by ParseFile when a .vue file cannot be parsed.
RenderError
type RenderError struct { Component string // component name being rendered Expr string // expression that triggered the error (may be empty) Wrapped error // underlying error Location *SourceLocation // source position, or nil if unknown }
Returned by render methods when template evaluation fails. Implements Unwrap.
ValidationError
type ValidationError struct { Component string // name of the component with the problem Message string // description of the problem }
One entry per problem in the slice returned by ValidateAll.
SourceLocation
type SourceLocation struct { File string // source file path Line int // 1-based line number (0 = unknown) Column int // 1-based column (0 = unknown) Snippet string // ~3-line context around the error (may be empty) }
ConversionError
type ConversionError struct { Component string // component being converted Directive string // directive involved (may be empty) Message string // human-readable description Location *SourceLocation // source position, or nil if unknown Cause error // underlying error (may be nil) } var ErrConversion
Returned by CompileToTemplate and RegisterTemplate when a component cannot be converted to an html/template-compatible representation. errors.Is(err, htmlc.ErrConversion) is true for all conversion failures.
MissingPropFunc / handlers
type MissingPropFunc func(name string) (any, error) func ErrorOnMissingProp(name string) (any, error) func SubstituteMissingProp(name string) (any, error)
MissingPropFunc— signature for missing-prop handlers; receive the prop name, return a substitute value or an error.ErrorOnMissingProp— aborts rendering with an error whenever a prop is absent. Use for strict validation.SubstituteMissingProp— returns"MISSING PROP: <name>"as a placeholder string.
Sentinel errors
var ErrComponentNotFound = errors.New("htmlc: component not found") var ErrMissingProp = errors.New("htmlc: missing required prop") var ErrConversion // sentinel for html/template conversion errors
ErrComponentNotFound— wrapped inside the error returned by render methods when the requested component name is not registered.ErrMissingProp— returned (wrapped) when a required prop is absent and noMissingPropFunchas been set.ErrConversion— sentinel forConversionErrorvalues returned byCompileToTemplateandRegisterTemplate.
if errors.Is(err, htmlc.ErrComponentNotFound) { http.NotFound(w, r) return }
html/template Interop
These methods allow components to be used with Go's standard html/template package — either by compiling htmlc components into *html/template.Template values, or by registering existing Go templates as components.
CompileToTemplate
func (e *Engine) CompileToTemplate(componentName string) (*html/template.Template, error)
Compiles the named component to a *html/template.Template. Returns a ConversionError (sentinel: ErrConversion) if the component uses features that cannot be expressed in Go's template language.
RegisterTemplate
func (e *Engine) RegisterTemplate(name string, tmpl *html/template.Template) error
Registers an existing *html/template.Template as an htmlc component under name. Other components may then use <Name></Name> to embed it. Returns a ConversionError if the template cannot be adapted.
TemplateText
func (e *Engine) TemplateText(componentName string) (text string, warnings []string, err error)
Returns the html/template-compatible template source text for the named component, along with any non-fatal warnings produced during conversion. Useful for inspecting the generated template text or for integrating with other template engines.
text, warnings, err := engine.TemplateText("NavBar") if err != nil { log.Fatal(err) } for _, w := range warnings { log.Println("warning:", w) } fmt.Println(text)