Skip to Content

i18n

The i18n package provides internationalization support including translation file loading, locale detection from HTTP requests, message formatting with parameter interpolation, and pluralization rules.

Import

import "github.com/gofastadev/gofasta/pkg/i18n"

Key Types

I18n

type I18n interface { T(locale string, key string, params ...interface{}) string TPlural(locale string, key string, count int, params ...interface{}) string HasLocale(locale string) bool Locales() []string SetFallback(locale string) }

I18nConfig

type I18nConfig struct { DefaultLocale string `yaml:"default_locale" env:"I18N_DEFAULT_LOCALE"` FallbackLocale string `yaml:"fallback_locale" env:"I18N_FALLBACK_LOCALE"` TranslationDir string `yaml:"translation_dir" env:"I18N_TRANSLATION_DIR"` }

LocaleDetector

type LocaleDetector interface { Detect(r *http.Request) string }

Key Functions

FunctionSignatureDescription
Newfunc New(cfg I18nConfig) (I18n, error)Creates a new i18n instance and loads translation files
NewLocaleDetectorfunc NewLocaleDetector(cfg I18nConfig) LocaleDetectorCreates a detector that reads Accept-Language headers
Middlewarefunc Middleware(i I18n, detector LocaleDetector) func(http.Handler) http.HandlerInjects the detected locale into the request context
LocaleFromContextfunc LocaleFromContext(ctx context.Context) stringRetrieves the detected locale from context

Translation Files

Create JSON translation files in your translations directory. Each file is named by its locale code.

translations/en.json:

{ "greeting": "Hello, {name}!", "items_count": { "one": "You have {count} item", "other": "You have {count} items" }, "errors": { "not_found": "The {resource} was not found", "unauthorized": "You must be logged in to perform this action" } }

translations/fr.json:

{ "greeting": "Bonjour, {name} !", "items_count": { "one": "Vous avez {count} article", "other": "Vous avez {count} articles" }, "errors": { "not_found": "Le {resource} n'a pas ete trouve", "unauthorized": "Vous devez etre connecte pour effectuer cette action" } }

Usage

Basic Translation

translator, err := i18n.New(i18n.I18nConfig{ DefaultLocale: "en", FallbackLocale: "en", TranslationDir: "translations/", }) if err != nil { log.Fatalf("failed to load translations: %v", err) } msg := translator.T("en", "greeting", "name", "Jane") // -> "Hello, Jane!" msg = translator.T("fr", "greeting", "name", "Jane") // -> "Bonjour, Jane !"

Pluralization

msg := translator.TPlural("en", "items_count", 1, "count", 1) // -> "You have 1 item" msg = translator.TPlural("en", "items_count", 5, "count", 5) // -> "You have 5 items"

Nested Keys

msg := translator.T("en", "errors.not_found", "resource", "user") // -> "The user was not found"

Locale Detection Middleware

detector := i18n.NewLocaleDetector(i18n.I18nConfig{ DefaultLocale: "en", }) mux.Handle("/api/", i18n.Middleware(translator, detector)(apiHandler))

Using Locale in Handlers

func (c *UserController) Create(w http.ResponseWriter, r *http.Request) { locale := i18n.LocaleFromContext(r.Context()) user, err := c.service.Create(r.Context(), input) if err != nil { msg := c.translator.T(locale, "errors.creation_failed") httputil.Error(w, errors.BadRequest(msg)) return } msg := c.translator.T(locale, "user_created") httputil.Created(w, msg, user) }

Configuration via config.yaml

i18n: default_locale: en fallback_locale: en translation_dir: translations/
  • Middleware — Locale detection middleware
  • Errors — Localized error messages
  • Mailer — Localized email templates
Last updated on