A Go library for locale-related data and functionality with zero external dependencies.
- BCP 47 Tag Parsing: Parse and normalize language tags like
en-US,zh-Hans-CN - Locale Fallback: Automatic fallback chains (e.g.,
fr-CA→fr→en) - Translation Bundles: Message translation with template variable substitution
- CLDR Pluralization: Full support for plural categories (zero, one, two, few, many, other)
- Embedded Defaults: Ships with translations for 6 locales (en, de, es, fr, ja, zh)
- Override Support: Customize any embedded data with your own translations
go get github.com/grokify/structured-localeimport "github.com/grokify/structured-locale/locale"
// Parse a BCP 47 tag
tag, err := locale.Parse("zh-Hans-CN")
if err != nil {
log.Fatal(err)
}
fmt.Println(tag.Language) // "zh"
fmt.Println(tag.Script) // "Hans"
fmt.Println(tag.Region) // "CN"
fmt.Println(tag.String()) // "zh-Hans-CN"
// Get parent for fallback
parent := tag.Parent() // "zh-Hans"import "github.com/grokify/structured-locale/locale"
// Get fallback chain for a locale
chain := locale.FallbackChain("fr-CA", "en")
// Returns: ["fr-CA", "fr", "en"]import "github.com/grokify/structured-locale/messages"
// Create a bundle with embedded defaults
bundle := messages.NewBundle()
// Get a localizer for French
loc := bundle.Localizer("fr")
// Simple translation
fmt.Println(loc.T("category.added")) // "Ajouté"
fmt.Println(loc.T("category.fixed")) // "Corrigé"
// Translation with variables
fmt.Println(loc.Tf("greeting", map[string]any{
"Name": "Alice",
})) // "Bonjour, Alice!"
// Plural translation
fmt.Println(loc.Tn("items.count", 1)) // "1 élément"
fmt.Println(loc.Tn("items.count", 5)) // "5 éléments"import "github.com/grokify/structured-locale/messages"
// Load custom translations from a file
bundle := messages.NewBundle()
err := bundle.LoadFile("fr", "custom-fr.json")
if err != nil {
log.Fatal(err)
}
// Or load from embedded data
//go:embed locales/*.json
var localesFS embed.FS
err = bundle.LoadFS(localesFS, "locales")Translation files use a simple JSON format:
[
{
"id": "category.added",
"translation": "Added"
},
{
"id": "items.count",
"translation": {
"one": "{{.Count}} item",
"other": "{{.Count}} items"
}
}
]See schema/messages-v1.schema.json for the full JSON Schema.
Built-in translations are provided for:
| Code | Language |
|---|---|
| en | English |
| de | German |
| es | Spanish |
| fr | French |
| ja | Japanese |
| zh | Chinese |
| Package | Description |
|---|---|
locale |
BCP 47 tag parsing, normalization, fallback logic |
messages |
Translation bundles, pluralization, message formatting |
See PRD.md for the full roadmap including planned packages for countries, phones, currencies, languages, dates, numbers, and addresses.
MIT License - see LICENSE for details.