go 17 lines · 1 tab

Template rendering with html/template and strict escaping

Leah Thompson Jan 2026
1 tab
package web

import (
  "bytes"
  "html/template"
  "net/http"
)

func Render(w http.ResponseWriter, t *template.Template, name string, data any) error {
  var buf bytes.Buffer
  if err := t.ExecuteTemplate(&buf, name, data); err != nil {
    return err
  }
  w.Header().Set("Content-Type", "text/html; charset=utf-8")
  _, err := w.Write(buf.Bytes())
  return err
}
1 file · go Explain with highlit

Even in API-heavy systems, I occasionally render HTML emails or a lightweight admin page. I always use html/template (not text/template) so content is escaped by default, which prevents accidental XSS when variables contain user input. I also keep templates parsed at startup so errors surface during boot, not under traffic. The helper below renders to a bytes.Buffer first, then writes a complete response, which avoids partial output if execution fails. Another operational detail: templates should be treated like code and tested with representative data; a missing field can cause a runtime error if you’re not careful. For emails, I render both a plain-text and HTML variant and keep subject lines separate. This is a safe, boring approach that avoids the “string concatenation HTML” trap.


Related snips

Share this code

Here's the card — post it anywhere.

Template rendering with html/template and strict escaping — share card
Link copied