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
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:
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
# 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
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
Reihenfolge: Prüft die Quellen standardmäßig in dieser Reihenfolge:
- Query-Parameter (?lang=ar)
- Cookie (language=ar)
- Accept-Language-Header
Zwischenspeicherung: Speichert die erkannte Sprache in einem Cookie, standardmäßig für ein Jahr
Fallback: Verwendet
fallbackLanguage, wenn keine gültige Sprache erkannt wird; muss insupportedLanguagesenthalten sein
Erweiterte Konfiguration
Eigene Erkennungsreihenfolge
Erkennung anhand des URL-Pfads bevorzugen, z. B. /en/about:
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.
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:
app.use(
languageDetector({
convertDetectedLanguage: (lang) => lang.split('-')[0],
supportedLanguages: ['en', 'ja'],
fallbackLanguage: 'en',
})
)Cookie-Konfiguration
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:
languageDetector({
caches: false,
})Debugging
Erkennungsschritte protokollieren:
languageDetector({
debug: true, // Shows: "Detected from querystring: ar"
})Optionsreferenz
Grundlegende Optionen
| Option | Typ | Standardwert | Erforderlich | Beschreibung |
|---|---|---|---|---|
supportedLanguages | string[] | ['en'] | Ja | Erlaubte Sprachcodes |
fallbackLanguage | string | 'en' | Ja | Standardsprache |
order | DetectorType[] | ['querystring', 'cookie', 'header'] | Nein | Erkennungsreihenfolge |
debug | boolean | false | Nein | Protokollierung aktivieren |
Erkennungsoptionen
| Option | Typ | Standardwert | Beschreibung |
|---|---|---|---|
lookupQueryString | string | 'lang' | Name des Query-Parameters |
lookupCookie | string | 'language' | Cookie-Name |
lookupFromHeaderKey | string | 'accept-language' | Header-Name |
lookupFromPathIndex | number | 0 | Index des Pfadsegments |
Cookie-Optionen
| Option | Typ | Standardwert | Beschreibung |
|---|---|---|---|
caches | CacheType[] | false | ['cookie'] | Cache-Einstellungen |
cookieOptions.path | string | '/' | Cookie-Pfad |
cookieOptions.sameSite | 'Strict' | 'Lax' | 'None' | 'Strict' | SameSite-Richtlinie |
cookieOptions.secure | boolean | true | Nur HTTPS |
cookieOptions.maxAge | number | 31536000 | Gültigkeitsdauer in Sekunden |
cookieOptions.httpOnly | boolean | true | Zugänglichkeit über JS |
cookieOptions.domain | string | undefined | Cookie-Domain |
Erweiterte Optionen
| Option | Typ | Standardwert | Beschreibung |
|---|---|---|---|
ignoreCase | boolean | true | Abgleich ohne Beachtung der Groß-/Kleinschreibung |
convertDetectedLanguage | (lang: string) => string | undefined | Funktion zur Umwandlung des Sprachcodes |
Validierung und Fehlerbehandlung
fallbackLanguagemuss insupportedLanguagesenthalten sein; andernfalls tritt beim Einrichten ein Fehler auflookupFromPathIndexmuss ≥ 0 sein- Ungültige Konfigurationen lösen bei der Initialisierung der Middleware Fehler aus
- Wenn die Erkennung fehlschlägt, wird ohne Fehlermeldung
fallbackLanguageverwendet
Häufige Rezepte
Pfadbasiertes Routing
app.get('/:lang/home', (c) => {
const lang = c.get('language') // 'en', 'ar', etc.
return c.json({ message: getLocalizedContent(lang) })
})Mehrere unterstützte Sprachen
languageDetector({
supportedLanguages: ['en', 'en-GB', 'ar', 'ar-EG'],
convertDetectedLanguage: (lang) => lang.replace('_', '-'), // Normalize
})