Localization (i18n)
The locale package provides internationalization support. Register translations per locale, resolve strings with T(), and auto-detect locale from Accept-Language headers via middleware.
Setup
import "github.com/CodeSyncr/nimbus/locale"
func init() {
// Set default locale
locale.SetDefault("en")
// Register English translations
locale.AddTranslations("en", map[string]string{
"welcome": "Welcome, %s!",
"items.count": "You have %d items",
"auth.login": "Log In",
"auth.logout": "Log Out",
"errors.not_found": "Page not found",
})
// Register Spanish translations
locale.AddTranslations("es", map[string]string{
"welcome": "¡Bienvenido, %s!",
"items.count": "Tienes %d artículos",
"auth.login": "Iniciar sesión",
"auth.logout": "Cerrar sesión",
"errors.not_found": "Página no encontrada",
})
}
Translating Strings
Use T() with the default locale, or TLocale() for a specific locale:
// Uses default locale ("en")
msg := locale.T("welcome", "Jane") // "Welcome, Jane!"
count := locale.T("items.count", 5) // "You have 5 items"
// Specific locale
msg = locale.TLocale("es", "welcome", "Jane") // "¡Bienvenido, Jane!"
// Key fallback — if key not found, returns the key itself
msg = locale.T("unknown.key") // "unknown.key"
Middleware (Auto-detect)
The locale middleware parses Accept-Language and stores the locale in the request context:
// Add to global middleware
app.Router.Use(locale.Middleware())
Context Helpers
// In a controller — get locale from request context
func Dashboard(c *http.Context) error {
loc := locale.FromContext(c.Request.Context())
// loc might be "es", "fr", "en", etc.
welcome := locale.TLocale(loc, "welcome", user.Name)
return c.View("dashboard", map[string]any{
"welcome": welcome,
})
}
// Manually set locale on a context
ctx := locale.WithLocale(c.Request.Context(), "fr")
API Reference
| Function | Description |
|---|---|
SetDefault(loc) | Set the default locale (e.g. "en") |
AddTranslations(loc, msgs) | Register key→message pairs for a locale |
T(key, args...) | Translate using default locale; supports fmt.Sprintf args |
TLocale(loc, key, args...) | Translate using a specific locale |
WithLocale(ctx, loc) | Store locale in context |
FromContext(ctx) | Retrieve locale from context (empty string if not set) |
Middleware() | Auto-detect locale from Accept-Language header |
Using in Templates
{{-- Pass translated strings from controller --}}
<h1>{{ welcome }}</h1>
<a href="/login">{{ loginText }}</a>
Organizing Translations
For larger apps, organize translation files by locale and load them at boot:
package lang
var EN = map[string]string{
"welcome": "Welcome, %s!",
"items.count": "You have %d items",
"auth.login": "Log In",
"auth.logout": "Log Out",
"auth.register": "Register",
"nav.dashboard": "Dashboard",
"nav.settings": "Settings",
"errors.not_found": "Page not found",
"errors.forbidden": "Access denied",
}
// In kernel.go:
// locale.AddTranslations("en", lang.EN)
// locale.AddTranslations("es", lang.ES)
String Interpolation
Translation values use Go's fmt.Sprintf formatting. Use %s for strings, %d for integers, %f for floats. If no args are passed, the message is returned as-is. If the key is not found, the key itself is returned — which makes it safe to use untranslated keys during development.