i18n

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package i18n is a thin wrapper over nicksnyder/go-i18n that loads message catalogs from an fs.FS (typically an embed.FS), resolves the request language from an Accept-Language header, and localizes *errs.Error messages by their MessageID/Code with Args as template data.

Catalogs are JSON files named by BCP-47 tag, e.g. en.json, ru.json. Lookups fall back to the default language and then to the raw message id, so a missing translation degrades gracefully rather than erroring.

Usage

Embed the catalogs, build a Translator with a default language, install the Middleware to resolve the request language, then localize errors per request:

//go:embed locales/*.json
var locales embed.FS

tr, err := i18n.New("en", locales, "locales/en.json", "locales/ru.json")
if err != nil {
    return err
}

mux.Handle("/", tr.Middleware()(handler)) // sets request lang in context

// In a handler, localize an *errs.Error for the resolved language:
lang := i18n.LangFromContext(r.Context())
e := tr.TranslateError(lang, errs.From(err))
body, contentType, _ := e.Encode()

TranslateError keys off e.MessageID (or e.CodeStr when unset) and feeds e.Args as template data; it returns a copy and never mutates the input. For plain strings use Localize / LocalizeData directly.

Language resolution

Match picks the best supported language for an Accept-Language header value, returning DefaultLang when nothing matches. Middleware calls Match and stores the result via WithLang; LangFromContext reads it back downstream. New always registers a localizer for the default language even if no catalog file declares it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LangFromContext

func LangFromContext(ctx context.Context) string

LangFromContext returns the language stored by Middleware/WithLang, or "".

func RequestLang

func RequestLang(r *http.Request) string

RequestLang resolves the raw requested base language code for r: an explicit X-Language header wins, otherwise the highest-priority Accept-Language tag. The result is normalized to a base code (e.g. "kk-KZ" -> "kk") but is NOT constrained to the loaded catalogs — it is the single source of truth for the request language, which each subsystem maps to its own supported set (i18n via Match/localizerFor, the translation package via its own Match). Returns "" when no language is requested.

func WithLang

func WithLang(ctx context.Context, lang string) context.Context

WithLang stores the resolved language in ctx.

Types

type Translator

type Translator struct {
	// contains filtered or unexported fields
}

Translator localizes message ids into the configured languages.

func New

func New(defaultLang string, fsys fs.FS, files ...string) (*Translator, error)

New builds a Translator. defaultLang is the BCP-47 tag used as the bundle's fallback and when a requested language is unknown. files are paths within fsys to JSON catalogs (e.g. "locales/en.json").

func (*Translator) DefaultLang

func (t *Translator) DefaultLang() string

DefaultLang returns the configured default language tag.

func (*Translator) Localize

func (t *Translator) Localize(lang, id string) string

Localize returns the message for id in lang, falling back to the default language and then to id itself.

func (*Translator) LocalizeData

func (t *Translator) LocalizeData(lang, id string, data map[string]any) string

LocalizeData is Localize with template data for placeholders in the message.

func (*Translator) Match

func (t *Translator) Match(acceptLanguage string) string

Match resolves the best supported language for an Accept-Language header value, returning the default language when none matches.

func (*Translator) Middleware

func (t *Translator) Middleware() func(http.Handler) http.Handler

Middleware resolves the request language (RequestLang) and stores it in the request context for downstream handlers and TranslateError. It is the single source of truth for the per-request language: an explicit X-Language header wins, otherwise the primary Accept-Language tag. Other features (e.g. the translation package) read the result via LangFromContext rather than parsing headers again, mapping it to their own supported set.

func (*Translator) TranslateError

func (t *Translator) TranslateError(lang string, e *errs.Error) *errs.Error

TranslateError returns a copy of e whose Message is localized for lang using e.MessageID (or e.CodeStr when unset) as the key and e.Args as template data. When no translation exists the original message is preserved. e is not mutated; nil returns nil.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL