Koa i18n Middleware

raw JSON →
2.1.0 verified Thu Apr 23 auth: no javascript maintenance

koa-i18n is a lightweight internationalization (i18n) middleware for Koa applications, built upon the `i18n-2` library. The current stable version, 2.1.0, is designed for Koa 2.x, while a separate 1.x branch targets Koa 1.x applications. Release cadence appears to be tied to Koa's major versions, with `2.x` being the current 'next' major iteration as of its release 9 years ago. A key differentiator is its reliance on `koa-locale` for robust locale detection, supporting various strategies including query parameters, subdomains, cookies, HTTP headers (`Accept-Language`), URL segments, and top-level domains (TLD), with the flexibility to add custom detection functions. This allows developers to tailor how the application determines the user's preferred language, making it suitable for multi-lingual web services. It provides a simple API through `ctx.i18n.__()` for translating keys.

error TypeError: ctx.i18n.__ is not a function
cause `koa-i18n` middleware was not correctly applied, or `koa-locale` was not initialized before `koa-i18n`.
fix
Ensure locale(app); is called before app.use(i18n(app, {...}));. Also, confirm app.use(i18n(...)) is present and correctly configured.
error Error: koa-locale must be required!
cause `koa-locale` was imported/required but its initialization function `locale(app)` was not called or was called after `koa-i18n` was used.
fix
Add locale(app); before app.use(i18n(app, {...}));. Ensure koa-locale is a dependency and correctly imported/required.
error Translations for key 'some.key' not found in locale 'en'
cause The specified translation key does not exist in the active locale's file, or the locale files are not correctly loaded due to `directory` or `locales` configuration issues.
fix
Verify the key some.key exists in your locale file (e.g., en.json). Check the directory path in koa-i18n options and ensure locales array matches the filenames. The i18n-2 dependency koa-i18n uses does not support best-match fallbacks, only exact locale matches.
breaking `koa-i18n` has distinct major versions for different Koa versions: `koa-i18n@1.x` for Koa 1.x (generator-based middleware) and `koa-i18n@2.x` for Koa 2.x+ (async/await middleware). Ensure you install the correct version matching your Koa setup. The example in the README uses `koa-convert` to adapt generator functions to Koa 2.x's async middleware style, which is often not needed in purely async/await Koa 2.x+ applications.
fix For Koa 2.x+, ensure `koa-i18n@2.x` is installed. Modern Koa 2.x+ middleware should be `async (ctx, next) => { ... }` functions. Remove `koa-convert` if your middleware is already async/await.
breaking The `koa-locale` package is a mandatory dependency and *must* be initialized by calling `locale(app)` before `koa-i18n` is used as middleware. Failing to do so will result in runtime errors as `koa-i18n` depends on `koa-locale` to set up locale detection on the Koa application context.
fix Ensure `const locale = require('koa-locale');` and `locale(app);` are present and executed before `app.use(i18n(app, {...}));`.
gotcha The `locales` array in the configuration must precisely match the filenames of your locale definition files (e.g., `['zh-CN', 'en']` expects `./config/locales/zh-CN.json` and `./config/locales/en.json`). Mismatched names can lead to `koa-i18n` failing to load translations or falling back to an unexpected default.
fix Verify that entries in the `locales` array directly correspond to your locale filenames (excluding the file extension) in the `directory`.
gotcha When configuring locale detection `modes`, the order matters. The first mode that successfully detects a locale will be used, and subsequent modes will be ignored. Place your preferred or most specific detection methods earlier in the array.
fix Arrange the `modes` array with the highest priority detection methods at the beginning (e.g., 'query' often before 'header').
gotcha The package `koa-i18n` has not been updated in approximately 9 years. While functional, it might not leverage the latest Node.js features, Koa 3.x paradigms, or modern i18n practices like ICU MessageFormat or more advanced pluralization rules found in newer libraries. Consider alternatives like `koa-i18next` for more active development and features.
fix For new projects or if encountering limitations, evaluate more actively maintained i18n solutions for Koa, such as `koa-i18next` or `koa-i18n-next`.
npm install koa-i18n
yarn add koa-i18n
pnpm add koa-i18n

Demonstrates setting up `koa-i18n` middleware, initializing `koa-locale`, configuring locale detection modes, and performing basic string translation within a Koa application context. Includes a note on legacy `koa-convert` usage.

const Koa = require('koa');
const convert = require('koa-convert'); // Used for generator-based middleware compatibility
const locale = require('koa-locale'); // Essential for locale detection
const i18n = require('koa-i18n');

const app = new Koa();

// IMPORTANT: koa-locale must be initialized before koa-i18n
locale(app);

app.use(i18n(app, {
  directory: './config/locales', // Path to your locale files (e.g., zh-CN.json, en.json)
  locales: ['zh-CN', 'en'], // List of supported locales; defaultLocale should match a filename
  modes: [
    'query',      // Detect locale from query string: /?locale=en
    'subdomain',  // Detect locale from subdomain: en.myapp.com
    'cookie',     // Detect locale from cookie: Cookie: locale=zh-TW
    'header',     // Detect locale from Accept-Language header
    'url',        // Detect locale from URL path: /en/page
    'tld',        // Detect locale from top-level domain: myapp.cn
    function() { /* optional custom detection logic */ }
  ]
}));

app.use(async (ctx, next) => {
  // Access translated strings via ctx.i18n.__
  ctx.body = ctx.i18n.__('greeting'); // Assuming 'greeting' key in your locale files
  await next();
});

// Example using koa-convert for older generator-style middleware (optional)
app.use(convert(function *() {
  // Yield a render if you have a view engine configured
  // yield this.render('index', { title: this.i18n.__('pageTitle') });
}));

app.listen(3000, () => {
  console.log('Koa i18n app running on http://localhost:3000');
});

// Example locale file structure (e.g., ./config/locales/en.json):
// {"greeting": "Hello, Koa!", "pageTitle": "Welcome"}