Skip to main content

Go के अंतरराष्ट्रीयकरण की संपूर्ण गाइड

मैसेज फ़ाइलों से लेकर goroutine-सुरक्षित लोकेल समाधान तक: go-i18n से अपने Go ऐप में i18n सेट अप करें, फिर AI की मदद से अनुवाद स्वचालित करें।

1

go-i18n इंस्टॉल करें

go-i18n, Go के लिए सबसे लोकप्रिय अंतरराष्ट्रीयकरण लाइब्रेरी है। यह CLDR के बहुवचन नियमों और वेरिएबल इंटरपोलेशन के लिए Go टेम्प्लेट का उपयोग करती है तथा JSON, TOML और YAML मैसेज फ़ाइलों का समर्थन करती है। भाषा टैग का मिलान करने के लिए आपको golang.org/x/text की भी आवश्यकता होगी।

go-i18n v2 के लिए Go 1.16+ आवश्यक है। golang.org/x/text पैकेज BCP 47 भाषा टैग को पार्स करने और उनका मिलान करने की सुविधा देता है, जिसका उपयोग go-i18n आंतरिक रूप से बहुवचन नियम चुनने के लिए करता है।
Terminal
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u golang.org/x/text/language
2

मैसेज फ़ाइलें बनाएँ

locales डायरेक्टरी में हर भाषा के लिए एक JSON फ़ाइल बनाएँ। प्रत्येक मैसेज में एक ID और बहुवचन के एक या अधिक रूप होते हैं। go-i18n वेरिएबल इंटरपोलेशन के लिए Go टेम्प्लेट सिंटैक्स (डॉट प्रीफ़िक्स वाली दोहरी कर्ली ब्रेसेज़) का उपयोग करता है।

locales/en.json
{
  "HelloWorld": { "other": "Hello, World!" },
  "Greeting": { "other": "Hello, {{.Name}}!" },
  "ItemCount": {
    "one": "{{.Count}} item",
    "other": "{{.Count}} items"
  },
  "WelcomeBack": {
    "other": "Welcome back, {{.Name}}. You have {{.Count}} messages."
  }
}
डॉट से अलग किए गए पाथ के बजाय 'ItemCount' या 'WelcomeBack' जैसे स्पष्ट मैसेज ID इस्तेमाल करें। go-i18n नेस्टेड कुंजियों के बजाय फ़्लैट ID का उपयोग करता है। Go की परंपराओं से मेल खाने के लिए ID को PascalCase में रखें।
3

Bundle लोड करें

Bundle, go-i18n की केंद्रीय रजिस्ट्री है। स्टार्टअप के समय इसे बनाएँ, अपना फ़ाइल फ़ॉर्मैट रजिस्टर करें और सभी मैसेज फ़ाइलें लोड करें। Bundle goroutine-सुरक्षित है—इसे केवल एक बार बनाएँ और अपने पूरे एप्लिकेशन में साझा करें।

main.go
package main

import (
    "encoding/json"
    "fmt"
    "github.com/nicksnyder/go-i18n/v2/i18n"
    "golang.org/x/text/language"
)

func main() {
    // 1. Create a bundle with a default language
    bundle := i18n.NewBundle(language.English)
    // 2. Register the unmarshal function for your file format
    bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
    // 3. Load message files
    bundle.MustLoadMessageFile("locales/en.json")
    bundle.MustLoadMessageFile("locales/ja.json")
    bundle.MustLoadMessageFile("locales/de.json")
    // 4. Create a localizer and localize a message
    localizer := i18n.NewLocalizer(bundle, "ja")
    msg := localizer.MustLocalize(&i18n.LocalizeConfig{
        MessageID: "HelloWorld",
    })
    fmt.Println(msg) // "こんにちは、世界!"
}
अगर आपको 'message not found' दिखाई दे, तो तीन चीज़ें जाँचें: 1) मैसेज फ़ाइल LoadMessageFile या MustLoadMessageFile से लोड की गई हो। 2) फ़ाइल एक्सटेंशन रजिस्टर किए गए अनमार्शल फ़ंक्शन से मेल खाता हो। 3) LocalizeConfig में मौजूद MessageID आपकी JSON फ़ाइल की कुंजी से हूबहू मेल खाता हो (अक्षरों के केस का भी मिलान आवश्यक है)।
4

Localizer का उपयोग करें

हर अनुरोध के लिए यूज़र की पसंदीदा भाषा के साथ एक Localizer बनाएँ। Localizer, Bundle से मैसेज प्राप्त करता है, Go के text/template इंजन से टेम्प्लेट रेंडरिंग संभालता है और PluralCount के आधार पर बहुवचन का सही रूप चुनता है।

Using the Localizer
// Simple message
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
    MessageID: "HelloWorld",
})

// Message with template data
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
    MessageID: "Greeting",
    TemplateData: map[string]interface{}{
        "Name": "Alice",
    },
})
// "Hello, Alice!" (en) or "こんにちは、Aliceさん!" (ja)

// Plural + template data
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
    MessageID: "ItemCount",
    PluralCount: 5,
    TemplateData: map[string]interface{}{
        "Count": 5,
    },
})
// "5 items" (en) or "5個のアイテム" (ja)

// Combined: plurals + multiple variables
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
    MessageID: "WelcomeBack",
    TemplateData: map[string]interface{}{
        "Name":  "Alice",
        "Count": 3,
    },
})
HTTP handler with locale detection
func handler(w http.ResponseWriter, r *http.Request) {
    // Accept-Language: ja,en;q=0.9,de;q=0.8
    accept := r.Header.Get("Accept-Language")

    // NewLocalizer accepts multiple languages — first match wins
    localizer := i18n.NewLocalizer(bundle, accept)

    msg := localizer.MustLocalize(&i18n.LocalizeConfig{
        MessageID: "HelloWorld",
    })

    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.Write([]byte(msg))
}
NewLocalizer कई भाषा स्ट्रिंग स्वीकार करता है और उन्हें क्रम से आज़माता है। Accept-Language हेडर सीधे पास करें: i18n.NewLocalizer(bundle, r.Header.Get("Accept-Language")). go-i18n हेडर को पार्स करके उपलब्ध अनुवादों से अपने-आप मिलान करता है।
5

बहुवचन नियम संभालें

go-i18n सभी भाषाओं के लिए CLDR बहुवचन नियम लागू करता है। अंग्रेज़ी में 2 रूप (one, other), अरबी में 6 (zero, one, two, few, many, other) और जापानी में 1 (other) होता है। अपनी मैसेज फ़ाइलों में सभी आवश्यक रूप निर्धारित करें—go-i18n, PluralCount के आधार पर सही रूप चुनता है।

Plural forms by language
// English: 2 forms (one, other)
{
  "ItemCount": {
    "one": "{{.Count}} item",
    "other": "{{.Count}} items"
  }
}

// Arabic: 6 forms (zero, one, two, few, many, other)
{
  "ItemCount": {
    "zero": "لا عناصر",
    "one": "عنصر واحد",
    "two": "عنصران",
    "few": "{{.Count}} عناصر",
    "many": "{{.Count}} عنصرًا",
    "other": "{{.Count}} عنصر"
  }
}

// Japanese: 1 form (other)
{
  "ItemCount": {
    "other": "{{.Count}}個のアイテム"
  }
}
Using plural rules
// go-i18n selects the correct plural form based on PluralCount
localizer := i18n.NewLocalizer(bundle, "ar")

msg := localizer.MustLocalize(&i18n.LocalizeConfig{
    MessageID:   "ItemCount",
    PluralCount: 3,
    TemplateData: map[string]interface{}{
        "Count": 3,
    },
})
// Arabic "few" form: "3 عناصر"

msg = localizer.MustLocalize(&i18n.LocalizeConfig{
    MessageID:   "ItemCount",
    PluralCount: 1,
    TemplateData: map[string]interface{}{
        "Count": 1,
    },
})
// Arabic "one" form: "عنصر واحد"
PluralCount और TemplateData अलग-अलग हैं। PluralCount बहुवचन रूप चुनता है, जबकि TemplateData टेम्प्लेट रेंडरिंग के लिए मान देता है। अगर मैसेज टेक्स्ट में संख्या चाहिए, तो उसे दोनों में पास करें: PluralCount: n और TemplateData: map[string]interface{'}'{"Count": n}.
6

लोकेल की पहचान

वेब एप्लिकेशन में यूज़र की पसंदीदा भाषा कई स्रोतों से पहचानें: क्वेरी पैरामीटर, कुकीज़, Accept-Language हेडर या URL पाथ सेगमेंट। BCP 47 के अनुरूप भाषा चयन के लिए golang.org/x/text/language.Matcher का उपयोग करें।

Locale detection middleware
// detectLocale resolves the user's preferred language.
// Priority: query param > cookie > Accept-Language header > default
func detectLocale(r *http.Request, matcher language.Matcher) string {
    // 1. Explicit query parameter: ?lang=ja
    if lang := r.URL.Query().Get("lang"); lang != "" {
        tag, _, _ := matcher.Match(language.Make(lang))
        return tag.String()
    }
    // 2. Cookie from previous selection
    if cookie, err := r.Cookie("lang"); err == nil {
        tag, _, _ := matcher.Match(language.Make(cookie.Value))
        return tag.String()
    }
    // 3. Accept-Language header
    accept := r.Header.Get("Accept-Language")
    if accept != "" {
        tags, _, _ := language.ParseAcceptLanguage(accept)
        if len(tags) > 0 {
            tag, _, _ := matcher.Match(tags...)
            return tag.String()
        }
    }
    return "en" // 4. Default
}

// Usage:
matcher := language.NewMatcher([]language.Tag{
    language.English, language.Japanese,
    language.German, language.Spanish,
})

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    locale := detectLocale(r, matcher)
    localizer := i18n.NewLocalizer(bundle, locale)
    // ... use localizer
})
language.NewMatcher आपकी समर्थित भाषाओं में से सबसे अच्छा मिलान लौटाता है, यूज़र की मूल पसंद नहीं। अगर कोई यूज़र 'pt-BR' माँगता है और आप केवल 'pt' का समर्थन करते हैं, तो मैचर सही ढंग से 'pt' लौटाता है। मैचर के बिना आपको हर क्षेत्रीय वेरिएंट के लिए फ़ॉलबैक लॉजिक मैन्युअल रूप से बनाना होगा।
7

go-locale-chain से हर कुंजी का फ़ॉलबैक ठीक करें

go-i18n की एक ज्ञात सीमा है: किसी लोकेल का मिलान हो जाने के बाद (उसके कुछ अनुवाद लोड होने पर), अनुपलब्ध कुंजियाँ चेन के अगले लोकेल पर फ़ॉलबैक नहीं होतीं। आंशिक रूप से अनूदित pt-BR फ़ाइल वाले यूज़र को pt-PT या pt पर फ़ॉलबैक होने के बजाय खाली स्ट्रिंग मिलती हैं। go-locale-chain, 75 बिल्ट-इन लोकेल चेन में हर कुंजी के लिए फ़ॉलबैक समाधान देकर इसे ठीक करता है।

Terminal
go get github.com/i18n-agent/go-locale-chain
go-locale-chain with go-i18n
package main

import (
    "encoding/json"
    "fmt"

    "github.com/nicksnyder/go-i18n/v2/i18n"
    localechain "github.com/i18n-agent/go-locale-chain"
    "golang.org/x/text/language"
)

func main() {
    // 1. Configure fallback chains (call once at startup)
    localechain.Configure()

    // 2. Set up go-i18n bundle as usual
    bundle := i18n.NewBundle(language.English)
    bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
    bundle.MustLoadMessageFile("locales/en.json")
    bundle.MustLoadMessageFile("locales/pt.json")
    bundle.MustLoadMessageFile("locales/pt-PT.json")
    bundle.MustLoadMessageFile("locales/pt-BR.json")

    // 3. Resolve with per-key fallback
    result, _ := localechain.ResolveWithLoader("pt-BR", func(locale string) (map[string]string, error) {
        localizer := i18n.NewLocalizer(bundle, locale)
        messages := make(map[string]string)
        for _, id := range []string{"hello", "goodbye", "thanks"} {
            msg, err := localizer.Localize(&i18n.LocalizeConfig{MessageID: id})
            if err == nil {
                messages[id] = msg
            }
        }
        return messages, nil
    })

    fmt.Println(result["hello"])   // "Olá (BR)"   — from pt-BR
    fmt.Println(result["goodbye"]) // "Adeus (PT)" — fallback to pt-PT
    fmt.Println(result["thanks"])  // "Obrigado"   — fallback to pt
}
go-locale-chain शून्य बाहरी डिपेंडेंसी वाला एक ओपन-सोर्स Go पैकेज है। यह go-i18n का पूरक है—मैसेज लोडिंग, बहुवचन और टेम्प्लेट रेंडरिंग के लिए go-i18n तथा सही फ़ॉलबैक चेन समाधान के लिए go-locale-chain का उपयोग करें।
Standalone usage (no go-i18n)
// Standalone: zero external dependencies, works with any format
localechain.Configure()

result, _ := localechain.ResolveWithLoader("es-MX", func(locale string) (map[string]string, error) {
    data, err := os.ReadFile(fmt.Sprintf("locales/%s.json", locale))
    if err != nil {
        return nil, err // Locale file doesn't exist — skip
    }
    var msgs map[string]string
    json.Unmarshal(data, &msgs)
    return msgs, nil
})
// es-MX -> es-419 -> es: each key resolved from most specific locale
डिफ़ॉल्ट को बनाए रखते हुए विशेष चेन कस्टमाइज़ करने के लिए ConfigureWithOverrides() का उपयोग करें। उदाहरण के लिए, pt-BR को सरल बनाकर केवल pt पर फ़ॉलबैक कराएँ या sv-FI -> sv जैसे किसी ऐसे लोकेल के लिए चेन जोड़ें जो डिफ़ॉल्ट में नहीं है।
8

अनुवाद स्वचालित करें

i18n सेटअप पूरा होने के बाद AI का उपयोग करके अपनी लोकेल फ़ाइलों का अनुवाद करें। अपनी अंग्रेज़ी स्रोत फ़ाइल से सभी लक्षित भाषाओं के अनुवाद सीधे IDE या CI/CD पाइपलाइन में तैयार करें।

Terminal
# In your IDE, ask your AI assistant:
> Translate locales/en.json to German, Japanese, and Spanish

✓ locales/de.json created (1.2s)
✓ locales/ja.json created (1.5s)
✓ locales/es.json created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate locales/en.json --lang de,ja,es
अनुवाद क्रमिक रूप से करें—स्रोत फ़ाइल में नए मैसेज ID जोड़ने पर सभी फ़ाइलें दोबारा बनाने के बजाय केवल नई कुंजियों का अनुवाद करें। इससे मनुष्यों द्वारा जाँचे गए अनुवाद सुरक्षित रहते हैं।

अनुवाद की गुणवत्ता स्वचालित करें

अनुपलब्ध कुंजियों और टूटे प्लेसहोल्डर को रिलीज़ से पहले पकड़ने के लिए i18n-validate का उपयोग करें। वास्तविक अनुवाद आने से पहले i18n-pseudo से छद्म-अनुवादों का उपयोग करके अपने UI की जाँच करें।

आम समस्याएँ

PluralCount और TemplateData का मेल न खाना

PluralCount बहुवचन रूप चुनता है, लेकिन मान को टेम्प्लेट में इंजेक्ट नहीं करता। रेंडर किए गए मैसेज में संख्या दिखाने के लिए आपको उसे TemplateData में भी पास करना होगा। TemplateData के बिना '{'{.Count}'}' का रेंडर किया हुआ मान '<no value>' होता है।

RegisterUnmarshalFunc अनुपलब्ध होना

अगर आप फ़ाइल फ़ॉर्मैट के लिए bundle.RegisterUnmarshalFunc() कॉल करना भूल जाते हैं, तो LoadMessageFile बिना कोई मैसेज दिए चुपचाप लौट जाता है। फ़ाइलें लोड करने से पहले हमेशा json.Unmarshal (या toml/yaml) रजिस्टर करें।

हर कुंजी का फ़ॉलबैक काम नहीं करता

go-i18n का NewLocalizer कई भाषाएँ स्वीकार करता है, लेकिन किसी लोकेल की एक कुंजी का मिलान होते ही अनुपलब्ध कुंजियाँ फ़ॉलबैक होने के बजाय खाली स्ट्रिंग लौटाती हैं। हर कुंजी के लिए सही क्रमिक फ़ॉलबैक लागू करने हेतु go-locale-chain का उपयोग करें।

टेम्प्लेट सिंटैक्स: {'{.Var}'}, न कि {'{Var}'}

go-i18n, Go के text/template सिंटैक्स का उपयोग करता है। वेरिएबल के आगे डॉट होना आवश्यक है: {'{.Name}'}, न कि {'{Name}'}। डॉट TemplateData मैप को संदर्भित करता है। डॉट न होने पर टेम्प्लेट निष्पादन में त्रुटि होती है।

सुझाई गई फ़ाइल संरचना

Project Structure
my-go-app/
├── locales/
│   ├── en.json           # Source language (English)
│   ├── de.json           # German translations
│   ├── ja.json           # Japanese translations
│   ├── es.json           # Spanish translations
│   ├── pt.json           # Portuguese (base)
│   ├── pt-PT.json        # Portuguese (Portugal)
│   └── pt-BR.json        # Portuguese (Brazil)
├── i18n/
│   ├── bundle.go         # Bundle initialization
│   ├── detect.go         # Locale detection logic
│   └── middleware.go      # HTTP middleware for locale
├── main.go
├── go.mod
└── go.sum

i18n Agent अभी आज़माएँ

अपनी अनुवाद फ़ाइल यहाँ छोड़ें

JSON, YAML, PO, XML, CSV, Markdown, Properties

या ब्राउज़ करने के लिए क्लिक करें

लक्षित भाषाएँ

साइन अप की ज़रूरत नहींतुरंत अनुमान

go-locale-chain के साथ लोकेल फ़ॉलबैक

जब pt-BR जैसे किसी क्षेत्रीय लोकेल में अनुवाद कुंजी अनुपलब्ध होती है, तो go-i18n पहले पैरेंट लोकेल pt की जाँच करने के बजाय सीधे डिफ़ॉल्ट भाषा पर चला जाता है।

Terminal
go get github.com/i18n-agent/go-locale-chain
Configuration
import localechain "github.com/i18n-agent/go-locale-chain"

chain := localechain.New(localechain.Config{
    Fallbacks: map[string][]string{
        "pt-BR":      {"pt", "en"},
        "zh-Hant-HK": {"zh-Hant", "zh", "en"},
    },
})

समर्थित फ़्रेमवर्क और 75 बिल्ट-इन चेन की पूरी सूची के लिए हमारी लोकेल फ़ॉलबैक गाइड देखें। Learn more →

Go i18n के अक्सर पूछे जाने वाले सवाल