Skip to main content

Overview

The language middleware detects user language preference from Accept-Language header, cookies, or query parameters. Use it when you need:
  • Multi-language support
  • Content localization
  • Language-based routing

Installation

import "github.com/go-mizu/mizu/middlewares/language"

Quick Start

app := mizu.New()

app.Use(language.New(language.Options{
    Supported: []string{"en", "es", "fr", "de"},
    Default:   "en",
}))

app.Get("/", func(c *mizu.Ctx) error {
    lang := language.Get(c)
    return c.JSON(200, map[string]string{"language": lang})
})

Configuration

Options

OptionTypeDefaultDescription
Supported[]stringRequiredSupported languages
DefaultstringFirst supportedDefault language
QueryKeystring"lang"Query parameter
CookieNamestring"lang"Cookie name

Examples

Basic Detection

app.Use(language.New(language.Options{
    Supported: []string{"en", "es", "fr"},
    Default:   "en",
}))

From Query Parameter

// GET /page?lang=es
app.Use(language.New(language.Options{
    Supported: []string{"en", "es"},
    QueryKey:  "language",
}))
app.Use(language.New(language.Options{
    Supported:  []string{"en", "es", "fr"},
    CookieName: "preferred_language",
}))

Language-Based Routing

app.Get("/:lang/page", func(c *mizu.Ctx) error {
    lang := c.Param("lang")
    // Validate and use language
    return c.JSON(200, getContent(lang))
})

Detection Order

  1. Query parameter (?lang=es)
  2. Cookie (lang=es)
  3. Accept-Language header
  4. Default language

API Reference

Functions

// New creates language middleware
func New(opts Options) mizu.Middleware

// Get returns detected language
func Get(c *mizu.Ctx) string

// Set sets language preference
func Set(c *mizu.Ctx, lang string)

Technical Details

Implementation Architecture

The language middleware uses a multi-source detection strategy with priority-based resolution:
  1. Context Storage: Detected language is stored in the request context using a private contextKey type
  2. Case-Insensitive Matching: All language comparisons are performed case-insensitively using lowercase normalization
  3. Regional Support: Handles both base language codes (e.g., “en”) and regional variants (e.g., “en-US”, “en-GB”)
  4. Quality-Based Parsing: Accept-Language header parsing respects quality values (q-values) for prioritization

Key Components

  • isSupported(): Validates if a language code exists in the supported languages map
  • normalize(): Converts detected language codes to the exact format defined in supported languages
  • parseAcceptLanguage(): Parses Accept-Language header with quality values, sorts by quality descending
  • Path Prefix Handling: When enabled, strips the language prefix from the URL path (e.g., /fr/page becomes /page)

Configuration Defaults

// Default values when not specified
QueryParam:  "lang"          // Query parameter name
CookieName:  "lang"          // Cookie name
Header:      "Accept-Language" // HTTP header
PathPrefix:  false           // Path prefix detection disabled
Default:     supported[0]    // First supported language

Best Practices

  • Support common language codes
  • Provide language switcher UI
  • Persist user preference
  • Use ISO 639-1 codes (en, es, fr)

Testing

The middleware includes comprehensive test coverage for all detection mechanisms and edge cases:
Test CaseDescriptionExpected Behavior
TestNewBasic middleware creation with Accept-Language headerDetects language from Accept-Language header (“es”)
TestWithOptions_QueryParamCustom query parameter detectionDetects language from query parameter “language=de”
TestWithOptions_CookieCustom cookie name detectionDetects language from cookie “user_lang=ja”
TestWithOptions_PathPrefixPath prefix language detectionDetects “fr” from “/fr/page” and strips prefix to “/page”
TestWithOptions_AcceptLanguageQualityQuality value parsing in Accept-LanguageSelects “fr” with q=0.9 over “en” with q=0.5
TestWithOptions_AcceptLanguageRegionRegional language variant detectionDetects exact match “en-GB” from regional variants
TestWithOptions_FallbackDefault language fallbackFalls back to “en” when unsupported language “zh” requested
TestWithOptions_PriorityDetection priority orderQuery parameter (“es”) takes priority over Accept-Language (“fr”)
TestFromContextContext retrieval alias functionGet() and FromContext() return identical values
TestWithOptions_NoHeaderNo language hints providedFalls back to default language “en”
TestWithOptions_CaseInsensitiveCase-insensitive language matchingMatches “es” query to “ES” in supported languages