i18n
Bueno's i18n module provides locale detection, translation lookups, pluralization, and number/date formatting.
Setup
import { createI18n } from '@buenojs/bueno/i18n';
const i18n = createI18n({
defaultLocale: 'en',
supportedLocales: ['en', 'es', 'fr', 'de'],
translationsDir: './locales',
});
await i18n.load(); // Load translation files
Translation files
Place JSON files in thetranslationsDir:
// locales/en.json
{
"greeting": "Hello, {{name}}!",
"item_count": {
"zero": "No items",
"one": "{{count}} item",
"other": "{{count}} items"
},
"nav": {
"home": "Home",
"about": "About",
"contact": "Contact"
}
}
// locales/es.json
{
"greeting": "¡Hola, {{name}}!",
"item_count": {
"zero": "Sin artículos",
"one": "{{count}} artículo",
"other": "{{count}} artículos"
},
"nav": {
"home": "Inicio",
"about": "Acerca de",
"contact": "Contacto"
}
}
Translating strings
const t = i18n.translator('es');
t('greeting', { name: 'María' }) // "¡Hola, María!"
t('nav.home') // "Inicio"
t('item_count', { count: 0 }) // "Sin artículos"
t('item_count', { count: 1 }) // "1 artículo"
t('item_count', { count: 5 }) // "5 artículos"
Middleware
Automatically detect locale from request headers and make it available in context:import { i18nMiddleware } from '@buenojs/bueno/i18n';
app.use(i18nMiddleware({
i18n,
detectFrom: ['header', 'cookie', 'query'],
// Checks: Accept-Language header, 'locale' cookie, ?locale= query param
}));
app.get('/welcome', (ctx) => {
const t = ctx.get('t'); // Translator for detected locale
return ctx.json({ message: t('greeting', { name: 'World' }) });
});
Number and date formatting
const fmt = i18n.formatter('de');
fmt.number(1234567.89) // "1.234.567,89"
fmt.currency(42.5, 'EUR') // "42,50 €"
fmt.date(new Date(), 'long') // "15. Januar 2025"
fmt.relativeTime(-5, 'minute') // "vor 5 Minuten"
Locale detection order
When usingi18nMiddleware, locale is detected in this priority order:
?locale=query parameterlocalecookieAccept-LanguageheaderdefaultLocalefallback
Supported locale formats
Standard BCP 47 locale tags:en, en-US, zh-Hant-TW, etc.