i18next / i18next-express-middleware

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

Cookies not being saved: user selected language lost #202

Closed alvarofrutos closed 4 years ago

alvarofrutos commented 4 years ago

I'm creating a simple Express webpage using i18next and i18next-express-middleware. My idea is that the language is detected but there is a button in the footer that allows the user to change the language. When this button is used it sends a GET query: ?lng=es

Detection is working fine. The language is correctly changed when the button is used. However the cookies are not saved and as soon the page is changed, the language does back to the detected one.

For example:

  1. Open "/" and the language is detected to Spanish (I'm from Madrid): OK
  2. Use the combo and open "/?lng=en", the page is loaded in English: OK
  3. Go to "/project/" and then the page is loaded back in Spanish: Not OK

My app.js looks like:

const i18next = require("i18next");
const i18back = require('i18next-node-fs-backend');
const i18midd = require("i18next-express-middleware");

...

i18next
  .use(i18back)
  .use(i18midd.LanguageDetector)
  .init({
    backend: {
      loadPath: __dirname + '/locales/{{lng}}.json',
      addPath: __dirname + '/locales/{{lng}}.missing.json'
    },
    fallbackLng: 'en',
    lowerCaseLng: true,
    preload: ['en', 'es'],
    whitelist: ['en', 'es'],
    nonExplicitWhitelist: true,
    saveMissing: true,
    detection: {
      order: ['querystring', 'cookie', 'header'],
      caches: ['cookie'],
      cookieDomain: 'test-domain.es',
      cookieSecure: false
    }
  });

...

app.use(i18midd.handle(i18next, {
  removeLngFromUrl: false
}));

The buttons are just links:

<a href="?lng=en">English</a>
<a href="?lng=es">Español</a>

I've tried using an additional middleware to detect the query and call req.i18n.changeLanguage manually but it's not working.

jamuhl commented 4 years ago

set debug: true and eventual you find some more information in the console logs...

alvarofrutos commented 4 years ago

Thank you. I'm not able to find the problem. Setting debug: true has revealed the following error:

i18next: languageChanged en
i18next: hasLoadedNamespace: i18n.languages were undefined or empty undefined
i18next::translator: key "index.title" for namespace "translation" for languages "en" won't get resolved as namespace was not yet loaded This means something IS WRONG in your application setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!

I've created a simple Express app with my web at: i18next-express-middleware-test.

Could you take a look to the code?

If I manage to make it work you could use that as an example in your project.

adrai commented 4 years ago

The cookie problem is probably just this: https://github.com/alvarofrutos/i18next-express-middleware-test/pull/1/files#diff-0364f57fbff2fabbe941ed20c328ef1aR31

alvarofrutos commented 4 years ago

Thanks. ¡That solved the issue! I still have that error from i18next though.

Please, feel free to use that example as part of your project if you want.

adrai commented 4 years ago

seems it happens just the first time t is called...