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 the translationsDir:
// 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 using i18nMiddleware, locale is detected in this priority order:
  1. ?locale= query parameter
  2. locale cookie
  3. Accept-Language header
  4. defaultLocale fallback

Supported locale formats

Standard BCP 47 locale tags: en, en-US, zh-Hant-TW, etc.

Released under the MIT License. Built with love by the Bueno Community.