i18next / i18next-express-middleware

[deprecated] can be replaced with i18next-http-middleware
https://github.com/i18next/i18next-http-middleware
MIT License
206 stars 52 forks source link

language detection does not work as expected #201

Open PAnilReddy opened 4 years ago

PAnilReddy commented 4 years ago

OS: windows Verisons used "i18next": "^11.2.3", "i18next-browser-languagedetector": "^2.1.0", "i18next-express-middleware": "^1.8.2", "i18next-xhr-backend": "^1.5.1",

I am using i18next with nodeJs express server. When any request flows into the server, the language is changed based on req.language but the key value of the message is always english I have the code something like this i18next .use(i18nextMiddleware.LanguageDetector)
.use(i18NodefsBackend) .init({ debug: true, preload: ['de','en','es','fr','it','ja','ko','pt','zh'], fallbackLng: ['en'], ns: ['translation'], backend: { loadPath: "src/server/locales/{{lng}}/{{ns}}.json" } });

app.use(i18nextMiddleware.handle(i18next));

and in my route handler I have this code function handler(req, res) { //i18next.changeLanguage(req.language); // LINE-1 i18next.t('unauthorized'); // I always get english strings }

When I un-comment LINE-1 this works. But I do not want to changeLanguage setting for every request and this is supposed to be handled by i18nextMiddleware.

In the logs I can see a message i18next: languageChanged de though the language is changed, the translated values is always in english. I tried all the options but could not figure out the issue.

jamuhl commented 4 years ago

you can't use 18next.t('unauthorized') that's accessing a singleton inside an async request -> think of concurrency of two requests having need for different language -> you won't get what you expect.

use req.t like shown: https://github.com/i18next/i18next-express-middleware#wire-up-i18next-to-request-object

PAnilReddy commented 4 years ago

I tried that as well, and the output of the line console.log(req.t('unauthorized')); is translation:unauthorized It does not give the translation key value

jamuhl commented 4 years ago

looks, like you calling t before translations were loaded...

jamuhl commented 4 years ago

beside that ... don't call changeLanguage of i18next - but the one you get in request...req.i18n.changeLanguage("en");

just keep in mind: concurrent request - using singleton is bad - only use what is on req.

PAnilReddy commented 4 years ago

Sure and Thank you. The translation files are loaded as the node server starts up. And the call what we are making is in the route request.. so the files are loaded and I can see them when the sever started when I have debug set to true and also before the route method is invoked I can see the language change happening as mentioned

jamuhl commented 4 years ago

well, seeing the key instead of the value is a clear sign of it does not exist (neither in detected nor in fallback language)...you will have to dig deeper as I can't...sorry...

jamuhl commented 4 years ago

you also might try req.i18n.changeLanguage("en", function() { console.log(req.t('unauthorized')); } );

PAnilReddy commented 4 years ago

I tired the above one as well... here is the output of all if you see the first line, it shows that the translations are loaded as it gives the value.

i18next.t('unauthorized') : User is not authorized to access req.t('unauthorized') : translation:unauthorized req.i18n.changeLanguage('en')... : translation:unauthorized

Am I missing anything... When should we defines the I18Next .. I did it globally in app.js of express

jamuhl commented 4 years ago

can you make a minimal sample for reproduction...honestly...I can't follow this by all the small snipplets pasted...

PAnilReddy commented 4 years ago

sure.. will make a sample and send it

PAnilReddy commented 4 years ago

I created a simple app, to check the language switch. and it does not work. I am using header/queryparam so that languagedetector kicks in but it does not happen. It would be great if you could help me out in fixing the issue.

i18next_sample_node_express.zip

image

jamuhl commented 4 years ago

did following changes:

var express = require('express');
var request = require('request');

var i18next = require('i18next');
var i18nextMiddleware = require("i18next-express-middleware");
var i18NodefsBackend = require('i18next-node-fs-backend');

i18next
    .use(i18nextMiddleware.LanguageDetector)
    .use(i18NodefsBackend)
    .init({
        debug: true,
        preload: ['de','en','zh'],
        fallbackLng: ['en'],
        ns: ['translation'],
        backend: {
            loadPath: __dirname +  "/locales/{{lng}}/{{ns}}.json"
        }
});

var app = express();
module.exports.app = app;

app.use(i18nextMiddleware.handle(i18next));

app.get('/i18test', function (req, res) {
    //i18next.changeLanguage(req.headers["accept-language"]);
    console.log("i18next.t('unauthorized') : "+i18next.t('unauthorized'));
    console.log("req.t('unauthorized') : "+req.t('unauthorized'));
    res.send(req.language + '  ==  ' +req.t('unauthorized'));
});

app.listen(8443, function() {
    console.log("Server listening on port", 8443);
});

==> all works

http://localhost:8443/i18test --> en-US == User is not authorized to access http://localhost:8443/i18test?lng=de --> de == Benutzer nicht berechtigt zum Zugriff auf

What's the deal?

-> it even tells you it's not loading the translations in the log (if not correctly setting path with __dirname) -> like said it did not load --> sample: https://github.com/i18next/i18next-express-middleware/blob/master/examples/basic/index.js#L14

PAnilReddy commented 4 years ago

Yeah.. I dint include the src... that was correct in my case. The only difference I see is that moving the app.use(i18nextMiddleware.handle(i18next)); solved the issue Thank you

jamuhl commented 4 years ago

If you like this module don’t forget to star this repo. Make a tweet, share the word or have a look at our https://locize.com to support the devs of this project.

If you liked my support / work - I would enjoy a coffee sponsored using the “:purple_heart:Sponsor Button”.

There are many ways to help this project :pray: