I am setting up i18next middleware in my express handlebars app, i18next works for any translation I put as the fallbackLng, the problem is none of the i18next middleware features are working like for example getting the lng param from url
Here is my i18next init setup
import { filterNodesByGroups, getNodeLabel } from "@ory/integrations/ui"
import express, { Request, Response } from "express"
import handlebars from "express-handlebars"
import * as fs from "fs"
import * as https from "https"
import { middleware as middlewareLogger } from "./pkg/logger"
import { toUiNodePartial } from "./pkg/ui"
import {
register404Route,
register500Route,
registerErrorRoute,
registerHealthRoute,
registerLoginRoute,
registerRecoveryRoute,
registerRegistrationRoute,
registerSettingsRoute,
registerStaticRoutes,
registerVerificationRoute,
registerWelcomeRoute,
} from "./routes"
const i18next = require('i18next')
const i18nextMiddleware = require('i18next-http-middleware')
const Backend = require('i18next-fs-backend')
const HandlebarsI18n = require("handlebars-i18n");
const app = express()
console.log("were here")
i18next
.use(Backend)
// .use(languageDetector)
.use(i18nextMiddleware.LanguageDetector)
.init({
debug: true,
backend: {
// eslint-disable-next-line no-path-concat
loadPath: __dirname + '/i18n/{{lng}}/{{ns}}.json'
},
fallbackLng: 'en',
preload: ['en', 'fr'],
// nonExplicitSupportedLngs: true,
// supportedLngs: ['en', 'fr'],
load: 'languageOnly'
})
app.use(middlewareLogger)
app.set("view engine", "hbs")
app.use(i18nextMiddleware.handle(i18next))
HandlebarsI18n.init();
app.engine(
"hbs",
handlebars({
extname: "hbs",
layoutsDir: `${__dirname}/../views/layouts/`,
partialsDir: `${__dirname}/../views/partials/`,
defaultLayout: "main",
helpers: {
...require("handlebars-helpers")(),
jsonPretty: (context: any) => JSON.stringify(context, null, 2),
onlyNodes: filterNodesByGroups,
toUiNodePartial,
getNodeLabel: getNodeLabel,
},
}),
)
registerStaticRoutes(app)
registerHealthRoute(app)
registerLoginRoute(app)
registerRecoveryRoute(app)
registerRegistrationRoute(app)
registerSettingsRoute(app)
registerVerificationRoute(app)
registerWelcomeRoute(app)
registerErrorRoute(app)
app.get("/", (req: Request, res: Response) => {
res.redirect("welcome", 303)
})
register404Route(app)
register500Route(app)
const port = Number(process.env.PORT) || 3000
let listener = (proto: "http" | "https") => () => {
console.log(`Listening on ${proto}://0.0.0.0:${port}`)
}
if (process.env.TLS_CERT_PATH?.length && process.env.TLS_KEY_PATH?.length) {
const options = {
cert: fs.readFileSync(process.env.TLS_CERT_PATH),
key: fs.readFileSync(process.env.TLS_KEY_PATH),
}
https.createServer(options, app).listen(port, listener("https"))
} else {
app.listen(port, listener("http"))
}
Here is the new package example
The deprecated package has an example that is close to the new package here
What could be wrong with my initialization of i18next-http-middleware?
Edit: If I change the language in the url header from en to fr in the debug output I get several language changes between requests for example:
i18next: languageChanged en
i18next: languageChanged fr
{"level":"info","message":"HTTP GET ... "}
i18next: languageChanged en
i18next: languageChanged en-US
{"level":"info","message":"HTTP GET ... "}
i18next: languageChanged en
i18next: languageChanged en-US
{"level":"info","message":"HTTP GET ... "}
i18next: languageChanged en
i18next: languageChanged en-US
i18next: languageChanged en
i18next: languageChanged en-US
i18next: languageChanged en
i18next: languageChanged en-US
i18next: languageChanged en
i18next: languageChanged en-US
I think this is a problem of integration between https://github.com/Aller-Couleur/handlebars-i18n/ and https://github.com/i18next/i18next-http-middleware
i18next-http-middleware sets the language on a clone of i18next
instance that is reported on request (req.i18n
), while handlebars-i18n use the i18next global instance, and I don't see anyway it can be changed.
I opened an issue on handlebars-i18n: https://github.com/Aller-Couleur/handlebars-i18n/issues/43 as it could be an easy fix on their side.