Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

language detection does not work as expected #201

Open
PAnilReddy opened this issue Dec 4, 2019 · 14 comments
Open

language detection does not work as expected #201

PAnilReddy opened this issue Dec 4, 2019 · 14 comments

Comments

@PAnilReddy
Copy link

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
Copy link
Member

jamuhl commented Dec 4, 2019

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
Copy link
Author

PAnilReddy commented Dec 4, 2019

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
Copy link
Member

jamuhl commented Dec 4, 2019

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

@jamuhl
Copy link
Member

jamuhl commented Dec 4, 2019

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
Copy link
Author

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
Copy link
Member

jamuhl commented Dec 4, 2019

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
Copy link
Member

jamuhl commented Dec 4, 2019

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

@PAnilReddy
Copy link
Author

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
Copy link
Member

jamuhl commented Dec 4, 2019

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

@PAnilReddy
Copy link
Author

sure.. will make a sample and send it

@PAnilReddy
Copy link
Author

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
Copy link
Member

jamuhl commented Dec 4, 2019

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);
});
  • fixed the path (might be only structure of in this zip archive - but there is no /src/)
  • required the backend (import might work on your side)
  • added the app.get('/i18test', function (req, res) { after the express-middleware so that runs before route...
  • changed to use req.t for res.send

==> 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
Copy link
Author

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
Copy link
Member

jamuhl commented Dec 4, 2019

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 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants