i18next / i18next-http-backend

i18next-http-backend is a backend layer for i18next using in Node.js, in the browser and for Deno.
MIT License
443 stars 67 forks source link

Version 2.2.1 loadpath variable can't be override #119

Closed dovagueh closed 1 year ago

dovagueh commented 1 year ago

🐛 Bug Report

Basically I try to use a specific path folder to store my translation file using I18next-http-backend to load them. But I endup having a loading issue and file not found issue. it was like the path was already hardcoded in the backend because the url reported wasn't my own. I tried to use these parameters

loadPath: '/data/{lng}.json',
resGetPath: '/data/{{lng}}.json'

but it doesn't change anything the url the backend was trying is this one

/locales/{{lng}}/Translator.json'

This url haven't been configured by me

To Reproduce

A minimal reproducible example. A codesandbox example or similar or at least steps to reproduce the behavior: In version 2.2.1 just try to load a Json translation file from another folder instead of this one. /locales/{{lng}}/{{namespace}}.json' For me the code that create this bug is located in the provided part below

 function _readAny(languages, loadUrlLanguages, namespaces, loadUrlNamespaces, callback) {
      var _this2 = this;
      var loadPath = this.options.loadPath;
      if (typeof this.options.loadPath === 'function') {
        loadPath = this.options.loadPath(languages, namespaces);
      }
      loadPath = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.makePromise)(loadPath);
      loadPath.then(function (resolvedLoadPath) {
        if (!resolvedLoadPath) return callback(null, {});
        var url = _this2.services.interpolator.interpolate(resolvedLoadPath, {
          lng: languages.join('+'),
          ns: namespaces.join('+')
        });
        _this2.loadUrl(url, callback, loadUrlLanguages, loadUrlNamespaces);
      });
    }
  }, 

Clearly the loadpath variable is hardcoded due to the fact that the check for the provided variable will be validated. then it will use this value which is above all and will override the provided path. I think it should be inside the IF statement which is not the case here.

var url = _this2.services.interpolator.interpolate(resolvedLoadPath, {
          lng: languages.join('+'),
          ns: namespaces.join('+')

Expected behavior

A clear and concise description of what you expected to happen.

Your Environment

adrai commented 1 year ago

Your loadPath is wrong.

- loadPath: '/data/{lng}.json',
+ loadPath: '/data/{{lng}}.json',
adrai commented 1 year ago

btw: resGetPath is not an option for i18next-http-backend

dovagueh commented 1 year ago

Why my path is wrong ?

dovagueh commented 1 year ago

Why you put a loadpath parameter if it doesn't serve to provide the actual loadpath ?

adrai commented 1 year ago

because the interpolation needs double curly brackets

adrai commented 1 year ago

instead of loadPath: '/data/{lng}.json', write: loadPath: '/data/{{lng}}.json',

adrai commented 1 year ago

btw: if that still does not solve your issue, please provide a minimal reproducible example repository or codesandbox I can execute...

dovagueh commented 1 year ago

I have just tried same result

adrai commented 1 year ago

please provide a minimal reproducible example repository or codesandbox I can execute...

dovagueh commented 1 year ago

import i18n from "i18next"; import Backend from "i18next-http-backend"; import { initReactI18next } from "react-i18next";

//i18n.sync.resStore = {}; i18n .use(Backend) .use(initReactI18next) .init({ fallbackLng: false, lng: "fr", resGetPath: '/data/{{lng}}.json', attributes: ['t', 'i18n'], ns: ['Translator'], defaultNS: 'Translator', interpolation: { escapeValue: false, }, Backend:{ loadPath: '/data/{{lng}}.json', //loadPath: ${window.location.origin}/Data/{{lng}}.json, }, debug: true, react: { wait: true } }, (error, t) => { if(error) console.error(error); }); export default i18n;

adrai commented 1 year ago

This is just a code snipped, and not a reproducible example...

dovagueh commented 1 year ago

that's the code that is refusing to load the file when I import it my browser just tell me that the translation files is not found. the same code using the hardcoded link work. Meaning i just need to create the folders and the file. For me there is an issue somewhere as i didn't provide this link. maybe my init is wrong somewhere but looking at the documentation it doesn't look so. Looking at the code I have provided it seem to me that the URL value is hardcoded, but i may be wrong as well.

adrai commented 1 year ago

btw:

import i18n from "i18next";
import Backend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";

//i18n.sync.resStore = {};
i18n
  .use(Backend)
  .use(initReactI18next)
  .init({
    fallbackLng: false,
    lng: "fr",
    // resGetPath: '/data/{{lng}}.json', // this is probably an option for jquery-i18next
    // attributes: ['t', 'i18n'], // this is probably an option for jquery-i18next
    ns: ['Translator'],
    defaultNS: 'Translator',
    interpolation: {
      escapeValue: false,
    },
-    Backend: {
+    backend: {
      loadPath: '/data/{{lng}}.json',
      //loadPath: ${window.location.origin}/Data/{{lng}}.json,
    },
    debug: true,
    react: {
-      wait: true
+      useSuspence: true
    }
  }, (error, t) => {
  if(error) console.error(error);
  });

export default i18n;
dovagueh commented 1 year ago

Ok backend declaration was wrong. Thanks for the clarification.