Internationalization (i18n)
Statigo provides built-in internationalization support with JSON-based translations and multi-language routing.
Translation Files
Translations are stored as JSON in the translations/ directory:
translations/en.json:
{
"nav": {
"home": "Home",
"about": "About",
"contact": "Contact"
},
"pages": {
"home": {
"title": "Welcome",
"subtitle": "A fast web framework"
},
"about": {
"title": "About Us",
"description": "Learn more about our company"
}
}
}
translations/tr.json:
{
"nav": {
"home": "Anasayfa",
"about": "Hakkında",
"contact": "İletişim"
},
"pages": {
"home": {
"title": "Hoş Geldiniz",
"subtitle": "Hızlı bir web framework"
},
"about": {
"title": "Hakkımızda",
"description": "Şirketimiz hakkında daha fazla bilgi edinin"
}
}
}
Initialization
import "statigo/framework/i18n"
i18nInstance, err := i18n.New(translationsFS, "en")
if err != nil {
log.Fatal(err)
}
Parameters:
fs.FS- Filesystem containing translation filesdefaultLang- Default language code (e.g., "en")
Using Translations in Go
Get String Value
title := i18nInstance.Get("tr", "pages.home.title")
// Returns: "Hoş Geldiniz"
Get Raw Value (Any Type)
data := i18nInstance.GetRaw("en", "pages.home")
// Returns: map[string]interface{}{"title": "Welcome", "subtitle": "..."}
Get with Fallback
value := i18nInstance.GetWithFallback("fr", "pages.home.title", "en")
// Falls back to "en" if "fr" translation doesn't exist
Using Translations in Templates
Basic Translation
<h1>{{t "pages.home.title"}}</h1>
Nested Keys
<nav>
<a href="/">{{t "nav.home"}}</a>
<a href="/about">{{t "nav.about"}}</a>
</nav>
With Language Context
The t function automatically uses the current language from context:
<p>{{t "pages.home.description"}}</p>
Language Detection
Statigo detects language in this priority order:
- URL Path -
/en/or/tr/prefix - Cookie -
langcookie value - Accept-Language Header - Browser preferences
- Default - Configured default language
Language Middleware
import "statigo/framework/middleware"
langConfig := middleware.LanguageConfig{
SupportedLanguages: []string{"en", "tr"},
DefaultLanguage: "en",
SkipPaths: []string{"/robots.txt", "/sitemap.xml"},
SkipPrefixes: []string{"/static/", "/health/"},
}
r.Use(middleware.Language(i18nInstance, langConfig))
Accessing Current Language
In Handlers
import "statigo/framework/middleware"
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
lang := middleware.GetLanguage(r.Context())
// lang is "en", "tr", etc.
}
In Templates
<p>Current language: {{.Lang}}</p>
<a href="{{localePath "/about" .Lang}}">About</a>
Adding a New Language
- Create translation file:
translations/de.json:
{
"nav": {
"home": "Startseite",
"about": "Über uns"
}
}
- Add to supported languages:
languages := []string{"en", "tr", "de"}
routeRegistry := router.NewRegistry(languages)
- Add routes in routes.json:
{
"canonical": "/about",
"paths": {
"en": "/en/about",
"tr": "/tr/hakkinda",
"de": "/de/ueber-uns"
}
}
Translation Best Practices
Use dot notation for nested keys
{ "pages": { "home": { "title": "Home" } } }Group related translations together
{ "nav": {...}, "pages": {...}, "errors": {...} }Use descriptive keys rather than complete sentences
{ "form": { "email_label": "Email Address", "email_error": "Please enter a valid email" } }Keep translations synchronized across all languages
Provide fallbacks for missing translations
Pluralization
For pluralization, use object syntax:
{
"items": {
"zero": "No items",
"one": "1 item",
"other": "{{.Count}} items"
}
}
Then in Go:
count := len(items)
key := "items.zero"
if count == 1 {
key = "items.one"
} else if count > 1 {
key = "items.other"
}
text := i18nInstance.Get(lang, key)
Date/Time Localization
Use the formatDate and formatDateTime template functions:
<p>{{formatDate .Date "2006-01-02"}}</p>
<p>{{formatDateTime .Date "2006-01-02T15:04:05Z"}}</p>
For language-specific formats, create translation keys:
{
"dates": {
"short": "Jan 2, 2006",
"long": "January 2, 2006"
}
}