Zum Inhalt springen

Language-Middleware ​

Die Language-Detector-Middleware ermittelt die bevorzugte Sprache beziehungsweise Locale eines Benutzers automatisch aus verschiedenen Quellen und stellt sie über c.get('language') bereit. Zu den Erkennungsstrategien gehören Query-Parameter, Cookies, Header und URL-Pfadsegmente. Sie eignet sich besonders für Internationalisierung (i18n) und sprach- oder regionsspezifische Inhalte.

Import ​

ts
import { Hono } from 'hono'
import { languageDetector } from 'hono/language'

Grundlegende Verwendung ​

Erkenne die Sprache aus Query-String, Cookie und Header in der Standardreihenfolge und verwende bei Bedarf Englisch als Fallback:

ts
const app = new Hono()

app.use(
  languageDetector({
    supportedLanguages: ['en', 'ar', 'ja'], // Must include fallback
    fallbackLanguage: 'en', // Required
  })
)

app.get('/', (c) => {
  const lang = c.get('language')
  return c.text(`Hello! Your language is ${lang}`)
})

Client-Beispiele ​

sh
# Via path
curl http://localhost:8787/ar/home

# Via query parameter
curl http://localhost:8787/?lang=ar

# Via cookie
curl -H 'Cookie: language=ja' http://localhost:8787/

# Via header
curl -H 'Accept-Language: ar,en;q=0.9' http://localhost:8787/

Standardkonfiguration ​

ts
export const DEFAULT_OPTIONS: DetectorOptions = {
  order: ['querystring', 'cookie', 'header'],
  lookupQueryString: 'lang',
  lookupCookie: 'language',
  lookupFromHeaderKey: 'accept-language',
  lookupFromPathIndex: 0,
  caches: ['cookie'],
  ignoreCase: true,
  fallbackLanguage: 'en',
  supportedLanguages: ['en'],
  cookieOptions: {
    sameSite: 'Strict',
    secure: true,
    maxAge: 365 * 24 * 60 * 60,
    httpOnly: true,
  },
  debug: false,
}

Zentrale Verhaltensweisen ​

Erkennungsablauf ​

  1. Reihenfolge: Prüft die Quellen standardmäßig in dieser Reihenfolge:

    • Query-Parameter (?lang=ar)
    • Cookie (language=ar)
    • Accept-Language-Header
  2. Zwischenspeicherung: Speichert die erkannte Sprache in einem Cookie, standardmäßig für ein Jahr

  3. Fallback: Verwendet fallbackLanguage, wenn keine gültige Sprache erkannt wird; muss in supportedLanguages enthalten sein

Erweiterte Konfiguration ​

Eigene Erkennungsreihenfolge ​

Erkennung anhand des URL-Pfads bevorzugen, z. B. /en/about:

ts
app.use(
  languageDetector({
    order: ['path', 'cookie', 'querystring', 'header'],
    lookupFromPathIndex: 0, // /en/profile → index 0 = 'en'
    supportedLanguages: ['en', 'ar'],
    fallbackLanguage: 'en',
  })
)

Schrittweiser Locale-Abgleich ​

Wenn ein erkannter Locale-Code wie ja-JP nicht in supportedLanguages enthalten ist, kürzt die Middleware schrittweise die Untertags, um einen passenden Eintrag zu finden. Für zh-Hant-CN wird beispielsweise erst zh-Hant und dann zh versucht. Eine exakte Übereinstimmung wird immer bevorzugt.

ts
app.use(
  languageDetector({
    supportedLanguages: ['en', 'ja', 'zh-Hant'],
    fallbackLanguage: 'en',
  })
)

// Accept-Language: ja-JP → matches 'ja'
// Accept-Language: zh-Hant-CN → matches 'zh-Hant'

Sprachcodes umwandeln ​

Komplexe Codes vereinheitlichen, z. B. en-US → en:

ts
app.use(
  languageDetector({
    convertDetectedLanguage: (lang) => lang.split('-')[0],
    supportedLanguages: ['en', 'ja'],
    fallbackLanguage: 'en',
  })
)
ts
app.use(
  languageDetector({
    lookupCookie: 'app_lang',
    caches: ['cookie'],
    cookieOptions: {
      path: '/', // Cookie path
      sameSite: 'Lax', // Cookie same-site policy
      secure: true, // Only send over HTTPS
      maxAge: 86400 * 365, // 1 year expiration
      httpOnly: true, // Not accessible via JavaScript
      domain: '.example.com', // Optional: specific domain
    },
  })
)

Cookie-Zwischenspeicherung deaktivieren:

ts
languageDetector({
  caches: false,
})

Debugging ​

Erkennungsschritte protokollieren:

ts
languageDetector({
  debug: true, // Shows: "Detected from querystring: ar"
})

Optionsreferenz ​

Grundlegende Optionen ​

OptionTypStandardwertErforderlichBeschreibung
supportedLanguagesstring[]['en']JaErlaubte Sprachcodes
fallbackLanguagestring'en'JaStandardsprache
orderDetectorType[]['querystring', 'cookie', 'header']NeinErkennungsreihenfolge
debugbooleanfalseNeinProtokollierung aktivieren

Erkennungsoptionen ​

OptionTypStandardwertBeschreibung
lookupQueryStringstring'lang'Name des Query-Parameters
lookupCookiestring'language'Cookie-Name
lookupFromHeaderKeystring'accept-language'Header-Name
lookupFromPathIndexnumber0Index des Pfadsegments
OptionTypStandardwertBeschreibung
cachesCacheType[] | false['cookie']Cache-Einstellungen
cookieOptions.pathstring'/'Cookie-Pfad
cookieOptions.sameSite'Strict' | 'Lax' | 'None''Strict'SameSite-Richtlinie
cookieOptions.securebooleantrueNur HTTPS
cookieOptions.maxAgenumber31536000Gültigkeitsdauer in Sekunden
cookieOptions.httpOnlybooleantrueZugänglichkeit über JS
cookieOptions.domainstringundefinedCookie-Domain

Erweiterte Optionen ​

OptionTypStandardwertBeschreibung
ignoreCasebooleantrueAbgleich ohne Beachtung der Groß-/Kleinschreibung
convertDetectedLanguage(lang: string) => stringundefinedFunktion zur Umwandlung des Sprachcodes

Validierung und Fehlerbehandlung ​

  • fallbackLanguage muss in supportedLanguages enthalten sein; andernfalls tritt beim Einrichten ein Fehler auf
  • lookupFromPathIndex muss ≥ 0 sein
  • Ungültige Konfigurationen lösen bei der Initialisierung der Middleware Fehler aus
  • Wenn die Erkennung fehlschlägt, wird ohne Fehlermeldung fallbackLanguage verwendet

Häufige Rezepte ​

Pfadbasiertes Routing ​

ts
app.get('/:lang/home', (c) => {
  const lang = c.get('language') // 'en', 'ar', etc.
  return c.json({ message: getLocalizedContent(lang) })
})

Mehrere unterstützte Sprachen ​

ts
languageDetector({
  supportedLanguages: ['en', 'en-GB', 'ar', 'ar-EG'],
  convertDetectedLanguage: (lang) => lang.replace('_', '-'), // Normalize
})

Veröffentlicht unter der MIT-Lizenz.