i18next Middleware for Koa 2
koa-i18next-middleware is a specialized middleware designed to integrate the i18next internationalization (i18n) library with Koa 2 applications. It enables dynamic language detection within Koa APIs, supporting various strategies such as reading from querystring parameters, URL path segments, cookies, and sessions. The middleware also offers the flexibility to define custom language detection mechanisms. The current stable version, 1.1.12, has seen no significant updates for several years, with the last activity on its GitHub repository dating back approximately five years. This indicates that the project is largely unmaintained, and users should be cautious regarding long-term support, security patches, or compatibility with newer Node.js or Koa versions. Its primary utility lies in providing a direct, Koa-idiomatic integration for i18next's language detection and translation capabilities, catering specifically to the Koa 2 async/await paradigm.
Common errors
-
TypeError: app.use is not a function
cause The middleware is being used with a non-Koa application instance, or an older Koa 1.x application, which does not have the async `app.use` signature.fixEnsure your `app` object is an instance of `Koa()` from the `koa` package (version 2 or higher). -
TypeError: Cannot read properties of undefined (reading 'session') OR TypeError: ctx.session is undefined
cause Session-based language detection methods (e.g., `lookupSession`, `lookupMySession`) are enabled in the `i18next` detection configuration, but a Koa session middleware (like `koa-session`) has not been installed or applied to the Koa app.fixInstall `koa-session` (or your chosen session middleware) via `npm i koa-session` and then add `app.keys = ['your-secret-key']; app.use(session(app));` to your Koa application before applying `koa-i18next-middleware`. -
Error: i18next not initialized!
cause The `i18next.init()` method was not called or did not complete its asynchronous initialization before `i18m.getHandler()` was invoked.fixEnsure `i18next.init()` is called and its callback indicates readiness, or use async/await with `i18next.init()` to guarantee initialization completes before the middleware handler is registered with `app.use()`. -
ReferenceError: require is not defined
cause Attempting to use `const i18m = require('koa-i18next-middleware');` syntax in a pure ECMAScript Module (ESM) context (i.e., `"type": "module"` in `package.json` without a `require` shim).fixUse `import * as i18m from 'koa-i18next-middleware';` for ESM imports. Alternatively, if your project allows, revert to CommonJS by removing `"type": "module"` from `package.json`.
Warnings
- breaking This middleware is specifically designed for Koa 2 and requires Node.js versions that fully support async/await. It is not compatible with Koa 1.x or older Node.js runtimes.
- gotcha The `koa-i18next-middleware` project appears to be unmaintained. The last commit on its GitHub repository was approximately five years ago, and there have been no new releases since version 1.1.12. Users should be aware of the lack of ongoing support, bug fixes, or compatibility updates with newer Koa or Node.js versions. Consider `i18next-http-middleware` as a currently maintained alternative for Node.js frameworks like Koa.
- gotcha When enabling session-based language detection (e.g., `lookupSession`, `lookupMySession`), a separate Koa session middleware (e.g., `koa-session`) must be installed and configured *before* `koa-i18next-middleware` in your Koa application's middleware stack. Otherwise, `ctx.session` will be undefined, leading to errors.
- gotcha Configuring custom language detectors, as shown in the README, can be quite verbose and involves manually adding detector objects to the `i18m.LanguageDetector` instance. For simple use cases, this boilerplate might be excessive.
Install
-
npm install koa-i18next-middleware -
yarn add koa-i18next-middleware -
pnpm add koa-i18next-middleware
Imports
- koa-i18next-middleware
import * as i18m from 'koa-i18next-middleware';
const i18m = require('koa-i18next-middleware'); - LanguageDetector
import { LanguageDetector } from 'koa-i18next-middleware';const lngDetector = new i18m.LanguageDetector();
- getHandler
app.use(getHandler(i18next, options));
app.use(i18m.getHandler(i18next, options));
Quickstart
const Koa = require('koa');
const i18next = require('i18next');
const i18m = require('koa-i18next-middleware');
const session = require('koa-session'); // Required for session-based detection
const app = new Koa();
app.keys = ['some secret key']; // Required for koa-session
app.use(session(app)); // Initialize session middleware
// Add custom detector.
const lngDetector = new i18m.LanguageDetector();
lngDetector.addDetector({
name: 'mySessionDetector',
lookup(ctx, options) {
let found;
if (options.lookupSession && ctx && ctx.session) {
found = ctx.session[options.lookupMySession];
}
return found;
},
cacheUserLanguage(ctx, lng, options = {}) {
if (options.lookupMySession && ctx && ctx.session) {
ctx.session[options.lookupMySession] = lng;
}
}
});
i18next.use(lngDetector).init(
{
fallbackLng: 'en',
preload: ['en', 'es'],
resources: {
en: {
translation: {
key: 'hello world'
}
},
es: {
translation: {
key: 'es hello world es'
}
}
},
detection: {
order: [
'querystring',
'path',
'cookie',
'session',
'mySessionDetector'
],
lookupQuerystring: 'lng',
lookupParam: 'lng',
lookupFromPathIndex: 0,
lookupCookie: 'i18next',
lookupSession: 'lng',
lookupMySession: 'lang',
caches: ['cookie', 'mySessionDetector']
}
},
(err, t) => {
if (err) return console.error('i18next initialization failed', err);
console.log('i18next initialized. Example translation:', i18next.t('key'));
}
);
app.use(
i18m.getHandler(i18next, {
locals: 'locals',
ignoreRoutes: ['/no-lng-route']
})
);
app.use(async ctx => {
ctx.body = ctx.t('key'); // 'ctx.t' is provided by i18next
});
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Koa app listening on port ${port}`));