or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

collation.mdencoding.mdformatting.mdindex.mdlanguage.mdlocalization.mdsearch-and-security.mdtext-transformation.mdunicode.md
tile.json

language.mddocs/

Language Tags and Display

This document covers language tag parsing, validation, matching, and display name functionality based on BCP 47 and Unicode CLDR data.

Package Overview

  • language: BCP 47 language tag implementation
  • language/display: Display names for languages, scripts, and regions

Language Package

Import path: golang.org/x/text/language

Implements BCP 47 language tags and related functionality for language identification and matching.

Tag Type

// Tag represents a BCP 47 language tag
type Tag struct{}

// Parsing functions
func Parse(s string) (Tag, error)
func Make(s string) Tag
func MustParse(s string) Tag

// Composition functions
func Compose(part ...interface{}) (Tag, error)

// Accept-Language parsing
func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error)

Tag Methods

func (t Tag) String() string
func (t Tag) Base() (Base, Confidence)
func (t Tag) Script() (Script, Confidence)
func (t Tag) Region() (Region, Confidence)
func (t Tag) Raw() (b Base, s Script, r Region)
func (t Tag) Variants() []Variant
func (t Tag) Parent() Tag
func (t Tag) IsRoot() bool
func (t Tag) Extension(x byte) (ext Extension, ok bool)
func (t Tag) Extensions() []Extension
func (t Tag) TypeForKey(key string) string
func (t Tag) SetTypeForKey(key, value string) (Tag, error)
func (t Tag) MarshalText() (text []byte, err error)
func (t Tag) UnmarshalText(text []byte) error

Common Language Tags

var Und Tag // Undefined

// English variants
var English Tag
var AmericanEnglish Tag
var BritishEnglish Tag

// Spanish variants
var Spanish Tag
var EuropeanSpanish Tag
var LatinAmericanSpanish Tag

// French variants
var French Tag
var CanadianFrench Tag

// Other major languages
var German Tag
var Italian Tag
var Portuguese Tag
var BrazilianPortuguese Tag
var EuropeanPortuguese Tag
var Dutch Tag
var Russian Tag
var Japanese Tag
var Korean Tag
var Arabic Tag
var Hindi Tag
var Turkish Tag
var Polish Tag
var Ukrainian Tag
var Swedish Tag
var Danish Tag
var Norwegian Tag
var Finnish Tag
var Greek Tag
var Hebrew Tag
var Thai Tag
var Vietnamese Tag
var Indonesian Tag
var Malay Tag

// Chinese variants
var Chinese Tag
var SimplifiedChinese Tag
var TraditionalChinese Tag
var MandarinChinese Tag

Base Language Type

// Base is an ISO 639 language code
type Base struct{}

func ParseBase(s string) (Base, error)
func MustParseBase(s string) Base

func (b Base) String() string
func (b Base) ISO3() string
func (b Base) IsPrivateUse() bool

Script Type

// Script is a 4-letter ISO 15924 code
type Script struct{}

func ParseScript(s string) (Script, error)
func MustParseScript(s string) Script

func (s Script) String() string
func (s Script) IsPrivateUse() bool

Region Type

// Region is an ISO 3166-1 or UN M.49 code
type Region struct{}

func ParseRegion(s string) (Region, error)
func MustParseRegion(s string) Region
func EncodeM49(r int) (Region, error)

func (r Region) String() string
func (r Region) ISO3() string
func (r Region) M49() int
func (r Region) IsCountry() bool
func (r Region) IsGroup() bool
func (r Region) IsPrivateUse() bool
func (r Region) Canonicalize() Region
func (r Region) Contains(c Region) bool
func (r Region) TLD() (Region, error)

Variant Type

// Variant represents a registered variant
type Variant struct{}

func ParseVariant(s string) (Variant, error)

func (v Variant) String() string

Extension Type

// Extension is a single BCP 47 extension
type Extension struct{}

func ParseExtension(s string) (Extension, error)

func (e Extension) String() string
func (e Extension) Type() byte
func (e Extension) Tokens() []string

Language Matching

// Matcher matches preferred tags against supported tags
type Matcher interface {
    Match(t ...Tag) (tag Tag, index int, c Confidence)
}

func NewMatcher(t []Tag, options ...MatchOption) Matcher
func MatchStrings(m Matcher, lang ...string) (tag Tag, index int)

// MatchOption configures a Matcher
type MatchOption func(*matcher)

func PreferSameScript(preferSame bool) MatchOption

Confidence Type

// Confidence indicates the level of certainty
type Confidence int

const (
    No   Confidence = iota // No match
    Low                    // Most likely value from alternatives
    High                   // Generally assumed correct
    Exact                  // Exact match or explicitly specified
)

func (c Confidence) String() string

// Comprehends reports confidence for speaker understanding alternative
func Comprehends(speaker, alternative Tag) Confidence

Canonicalization

// CanonType specifies canonicalization types
type CanonType int

const (
    DeprecatedBase   CanonType = 1 << iota
    DeprecatedScript
    DeprecatedRegion
    SuppressScript
    Legacy
    Macro
    CLDR

    Raw        CanonType = 0
    Deprecated CanonType = DeprecatedBase | DeprecatedScript | DeprecatedRegion
    BCP47      CanonType = Deprecated | SuppressScript
    All        CanonType = BCP47 | Legacy | Macro
    Default    CanonType = Deprecated | Legacy
)

func (c CanonType) Canonicalize(t Tag) (Tag, error)
func (c CanonType) Compose(part ...interface{}) (Tag, error)
func (c CanonType) Make(s string) Tag
func (c CanonType) MustParse(s string) Tag
func (c CanonType) Parse(s string) (Tag, error)

Coverage and Compact Tags

// Coverage defines the level of coverage of an i18n service
type Coverage interface {
    Tags() []Tag
    BaseLanguages() []Base
    Scripts() []Script
    Regions() []Region
}

func NewCoverage(list ...interface{}) Coverage

var Supported Coverage // All supported subtags

// Compact tag indexing
const NumCompactTags int // Number of compact tags

func CompactIndex(t Tag) (index int, exact bool)

Errors

var ErrMissingLikelyTagsData error

// ValueError is returned when input is well-formed but subtag not recognized
type ValueError interface {
    error
    Subtag() string
}

Constants

const CLDRVersion string = "32"

Usage Examples

import "golang.org/x/text/language"

// Parse language tags
tag, err := language.Parse("en-US")
tag = language.Make("en-GB") // Panics on error
tag = language.English

// Get tag components
base, conf := tag.Base()      // Base language
script, conf := tag.Script()  // Script
region, conf := tag.Region()  // Region

// Compose tags from parts
tag, err = language.Compose(
    language.English,
    language.MustParseScript("Latn"),
    language.MustParseRegion("US"),
)

// Language matching for content negotiation
supported := []language.Tag{
    language.English,
    language.Spanish,
    language.German,
}
matcher := language.NewMatcher(supported)

// Match user preferences
userPrefs := []language.Tag{
    language.Make("es-MX"),
    language.Make("en"),
}
tag, index, conf := matcher.Match(userPrefs...)

// Parse Accept-Language header
tags, q, err := language.ParseAcceptLanguage("en-US,en;q=0.9,es;q=0.8")

// Check if speaker can comprehend alternative
conf := language.Comprehends(language.Spanish, language.Catalan)

// Work with regions
region := language.MustParseRegion("US")
iso3 := region.ISO3()      // "USA"
m49 := region.M49()        // 840
isCountry := region.IsCountry() // true

// Canonicalization
deprecated := language.Make("iw") // Hebrew (deprecated code)
canonical, _ := language.BCP47.Canonicalize(deprecated)
// canonical is now "he" (modern Hebrew code)

Language Display Package

Import path: golang.org/x/text/language/display

Provides display names for languages, scripts, and regions in various languages.

Namer Interface

// Namer returns names for given values
type Namer interface {
    Name(x interface{}) string
}

// Get Namers for a specific language
func Languages(t language.Tag) Namer
func Scripts(t language.Tag) Namer
func Regions(t language.Tag) Namer
func Tags(t language.Tag) Namer

Dictionary Type

// Dictionary holds Namers for a single language
type Dictionary struct{}

func (d *Dictionary) Languages() Namer
func (d *Dictionary) Scripts() Namer
func (d *Dictionary) Regions() Namer
func (d *Dictionary) Tags() Namer

Predefined Dictionaries

// Major languages
var Afrikaans *Dictionary
var Amharic *Dictionary
var Arabic *Dictionary
var ModernStandardArabic *Dictionary
var Azerbaijani *Dictionary
var Bulgarian *Dictionary
var Bengali *Dictionary
var Catalan *Dictionary
var Czech *Dictionary
var Danish *Dictionary
var German *Dictionary
var Greek *Dictionary
var English *Dictionary
var AmericanEnglish *Dictionary
var BritishEnglish *Dictionary
var Spanish *Dictionary
var EuropeanSpanish *Dictionary
var LatinAmericanSpanish *Dictionary
var Estonian *Dictionary
var Persian *Dictionary
var Finnish *Dictionary
var Filipino *Dictionary
var French *Dictionary
var CanadianFrench *Dictionary
var Gujarati *Dictionary
var Hebrew *Dictionary
var Hindi *Dictionary
var Croatian *Dictionary
var Hungarian *Dictionary
var Armenian *Dictionary
var Indonesian *Dictionary
var Icelandic *Dictionary
var Italian *Dictionary
var Japanese *Dictionary
var Georgian *Dictionary
var Kazakh *Dictionary
var Khmer *Dictionary
var Kannada *Dictionary
var Korean *Dictionary
var Kirghiz *Dictionary
var Lao *Dictionary
var Lithuanian *Dictionary
var Latvian *Dictionary
var Macedonian *Dictionary
var Malayalam *Dictionary
var Mongolian *Dictionary
var Marathi *Dictionary
var Malay *Dictionary
var Burmese *Dictionary
var Nepali *Dictionary
var Dutch *Dictionary
var Norwegian *Dictionary
var Punjabi *Dictionary
var Polish *Dictionary
var Portuguese *Dictionary
var BrazilianPortuguese *Dictionary
var EuropeanPortuguese *Dictionary
var Romanian *Dictionary
var Russian *Dictionary
var Sinhala *Dictionary
var Slovak *Dictionary
var Slovenian *Dictionary
var Albanian *Dictionary
var Serbian *Dictionary
var SerbianLatin *Dictionary
var Swedish *Dictionary
var Swahili *Dictionary
var Tamil *Dictionary
var Telugu *Dictionary
var Thai *Dictionary
var Turkish *Dictionary
var Ukrainian *Dictionary
var Urdu *Dictionary
var Uzbek *Dictionary
var Vietnamese *Dictionary
var Chinese *Dictionary
var SimplifiedChinese *Dictionary
var TraditionalChinese *Dictionary
var Zulu *Dictionary

SelfNamer Type

// SelfNamer returns language names in their own language
type SelfNamer struct {
    Supported language.Coverage
}

func (s *SelfNamer) Name(x interface{}) string

var Self *SelfNamer // Shared instance

Formatter Type

// Formatter formats tags for display
type Formatter struct{}

func Language(lang interface{}) Formatter
func Script(script interface{}) Formatter
func Region(region interface{}) Formatter
func Tag(tag interface{}) Formatter

func (f Formatter) Format(state format.State, verb rune)

Coverage

var Supported language.Coverage // Languages for which names are defined
var Values language.Coverage     // All possible values with names

Constants

const CLDRVersion string = "32"
const Version string = "32" // Deprecated: Use CLDRVersion

Usage Examples

import (
    "fmt"
    "golang.org/x/text/language"
    "golang.org/x/text/language/display"
)

// Get language names in different languages
enNamer := display.English.Languages()
fmt.Println(enNamer.Name(language.Spanish))  // "Spanish"
fmt.Println(enNamer.Name(language.Japanese)) // "Japanese"

esNamer := display.Spanish.Languages()
fmt.Println(esNamer.Name(language.English))  // "inglés"
fmt.Println(esNamer.Name(language.French))   // "francés"

// Get region names
regionNamer := display.English.Regions()
fmt.Println(regionNamer.Name(language.MustParseRegion("US"))) // "United States"
fmt.Println(regionNamer.Name(language.MustParseRegion("JP"))) // "Japan"

// Get script names
scriptNamer := display.English.Scripts()
fmt.Println(scriptNamer.Name(language.MustParseScript("Latn"))) // "Latin"
fmt.Println(scriptNamer.Name(language.MustParseScript("Cyrl"))) // "Cyrillic"

// Get full tag descriptions
tagNamer := display.English.Tags()
tag := language.Make("zh-Hans-CN")
fmt.Println(tagNamer.Name(tag)) // "Simplified Chinese (China)"

// Get language names in their own language (self-naming)
fmt.Println(display.Self.Name(language.Spanish))  // "español"
fmt.Println(display.Self.Name(language.Japanese)) // "日本語"
fmt.Println(display.Self.Name(language.Arabic))   // "العربية"

// Use standalone functions
langNamer := display.Languages(language.German)
fmt.Println(langNamer.Name(language.Italian)) // "Italienisch"

regionNamer = display.Regions(language.French)
fmt.Println(regionNamer.Name(language.MustParseRegion("CA"))) // "Canada"

// Use with fmt.Printf via Formatter
fmt.Printf("Language: %v\n", display.Language(language.Spanish))
fmt.Printf("Region: %v\n", display.Region(language.MustParseRegion("MX")))

Common Patterns

Content Negotiation

import (
    "net/http"
    "golang.org/x/text/language"
)

func handleRequest(w http.ResponseWriter, r *http.Request) {
    // Define supported languages
    supported := []language.Tag{
        language.English,
        language.Spanish,
        language.French,
        language.German,
    }
    matcher := language.NewMatcher(supported)

    // Parse Accept-Language header
    acceptLang := r.Header.Get("Accept-Language")
    tags, _, _ := language.ParseAcceptLanguage(acceptLang)

    // Match best language
    tag, index, conf := matcher.Match(tags...)

    // Use matched language for response
    // ...
}

Building Language Switcher UI

import (
    "golang.org/x/text/language"
    "golang.org/x/text/language/display"
)

type LanguageOption struct {
    Code string
    Name string
}

func getLanguageOptions(displayLang language.Tag) []LanguageOption {
    namer := display.Languages(displayLang)

    supported := []language.Tag{
        language.English,
        language.Spanish,
        language.French,
        language.German,
        language.Japanese,
        language.Chinese,
    }

    options := make([]LanguageOption, len(supported))
    for i, tag := range supported {
        options[i] = LanguageOption{
            Code: tag.String(),
            Name: namer.Name(tag),
        }
    }

    return options
}

Locale-Aware Routing

import (
    "strings"
    "golang.org/x/text/language"
)

func extractLanguageFromPath(path string) (language.Tag, string) {
    parts := strings.Split(strings.Trim(path, "/"), "/")
    if len(parts) == 0 {
        return language.English, path
    }

    // Try to parse first path component as language
    tag, err := language.Parse(parts[0])
    if err == nil {
        // Valid language tag found
        remainingPath := "/" + strings.Join(parts[1:], "/")
        return tag, remainingPath
    }

    // No language in path
    return language.English, path
}

Region Detection and Validation

import "golang.org/x/text/language"

func validateAndCanonicalizeRegion(code string) (language.Region, error) {
    region, err := language.ParseRegion(code)
    if err != nil {
        return language.Region{}, err
    }

    // Canonicalize deprecated regions
    region = region.Canonicalize()

    // Check if it's a real country (not a group)
    if !region.IsCountry() {
        return language.Region{}, fmt.Errorf("not a country: %s", code)
    }

    return region, nil
}

func getRegionHierarchy(region language.Region) []language.Region {
    // Get containing regions (e.g., US -> Americas -> World)
    hierarchy := []language.Region{region}

    // Check M.49 groups
    m49 := region.M49()
    // ... lookup parent regions from M.49 codes

    return hierarchy
}

Tag Comparison and Fallback

import "golang.org/x/text/language"

func findFallbackLanguage(requested language.Tag, available []language.Tag) language.Tag {
    // Try exact match
    for _, tag := range available {
        if tag == requested {
            return tag
        }
    }

    // Try base language match (ignore script/region)
    requestedBase, _ := requested.Base()
    for _, tag := range available {
        base, _ := tag.Base()
        if base == requestedBase {
            return tag
        }
    }

    // Try parent
    parent := requested.Parent()
    if !parent.IsRoot() {
        return findFallbackLanguage(parent, available)
    }

    // Default to first available
    if len(available) > 0 {
        return available[0]
    }

    return language.English
}

Custom Language Display

import (
    "golang.org/x/text/language"
    "golang.org/x/text/language/display"
)

type LocalizedName struct {
    Native  string // Name in its own language
    English string // Name in English
    Local   string // Name in user's language
}

func getLocalizedNames(tag language.Tag, userLang language.Tag) LocalizedName {
    return LocalizedName{
        Native:  display.Self.Name(tag),
        English: display.English.Languages().Name(tag),
        Local:   display.Languages(userLang).Name(tag),
    }
}

Version Information

Based on:

  • CLDR 32
  • BCP 47 (RFC 5646)
  • ISO 639 language codes
  • ISO 15924 script codes
  • ISO 3166-1 region codes
  • UN M.49 region codes