Skip to content

Internationalization

govalid is locale-aware end-to-end: rule messages, field labels and diagnostic templates can all be localized.

Bundled locales

LocaleTag
Chinese (default)language.Chinese
Englishlanguage.English

The default locale is Chinese. Override it by setting govalid.defaultTemplateLanguage is not exposed — pick a locale per call instead.

Per-call locale

Check accepts an optional language.Tag:

go
import "golang.org/x/text/language"

errs, ok := govalid.Check(form, language.English)

Selection rules:

  1. Use the requested locale's template set if it exists.
  2. If the locale isn't registered, fall back to the package default (Chinese).
  3. If a specific template key is missing inside the chosen locale, fall back to _unknownErrorTemplate.

Localized field labels

label-<lang> tags let you attach per-locale labels alongside the default label tag. The lang suffix matches language.Tag.String():

go
type Form struct {
    Email string `valid:"required" label:"邮箱" label-en:"Email"`
}

govalid.Check(form, language.English) // → "Email can not be empty"
govalid.Check(form, language.Chinese) // → "邮箱不能为空"

Lookup order per call:

  1. label-<lang> for the requested locale
  2. label
  3. The Go field name

Adding a new locale

SetMessageTemplates creates the locale on first use:

go
import "golang.org/x/text/language"

govalid.SetMessageTemplates(map[string]string{
    "required": " は必須です",
    "min":      " は %v 以上である必要があります",
}, language.Japanese)

You can override entries selectively — only the keys you provide are replaced; the rest fall back to the default locale per the rules above.

Choosing a locale at runtime

A common pattern is to derive the locale from an HTTP request:

go
func handler(w http.ResponseWriter, r *http.Request) {
    var form Form
    _ = json.NewDecoder(r.Body).Decode(&form)

    matcher := language.NewMatcher([]language.Tag{
        language.Chinese, language.English, language.Japanese,
    })
    accept, _, _ := language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
    tag, _, _ := matcher.Match(accept...)

    errs, ok := govalid.Check(form, tag)
    if !ok {
        // render `errs` to the client
    }
}

Diagnostic templates by locale

The five _-prefixed diagnostic templates are localized too. Override them per locale just like regular rule templates:

go
govalid.SetMessageTemplates(map[string]string{
    "_checkerNotFound":      "Unknown rule",
    "_paramError":           "Bad rule parameters",
    "_valueTypeError":       "Wrong field type",
    "_fieldNotFound":        "Referenced field not found",
    "_unknownErrorTemplate": "Validation failed",
}, language.English)

Released under the MIT License.