False warning about accessing t function before calling init #977
Comments
|
1.) you call init before calling render -> does not mean init was done before you called render!!! (init is async) https://github.com/i18next/i18next/blob/master/src/Translator.js#L345 calls https://github.com/i18next/i18next/blob/master/src/i18next.js#L296 ...your namespace not yet loaded It's the same logic that tests for ready in react-i18next -> did you set useSuspense: false ?!? |
|
In fact, I tried to call I don't know |
|
If useSuspense is false and you got somewhere a withTranslation or useTranslation loading a namespace - you also run into this |
|
Can you paste your i18next.init options and the component accessing the xxx key throwing that warning |
|
wondering...tests are passing for that feature...might be I miss something: https://github.com/i18next/i18next/blob/master/test/i18next.hasLoadedNamespace.spec.js |
|
I'm in the middle of something else but plan to get back to this as soon as possible. |
|
Might be I found some edgecase...might be the next update today will solve this false positive... Will ping you again with new versions to test... |
|
Can you retry with: react-i18next@11.0.0 |
|
I tried with: react-i18next@11.0.0 and got the same warnings. But I still haven't looked at |
|
a codesandbox for reproduction might help... |
|
|
|
Will need a sample to reproduce...as I don't get this on the example... |
|
In With So, this fails with Is it a bug on your side or am I using it the wrong way? |
|
No, it's the behaviour you get based on: https://www.i18next.com/principles/fallback#language-fallback If language is set to But still can't reproduce... the check checks if loading is not pending: https://github.com/i18next/i18next/blob/master/src/i18next.js#L340 having no success loading fr-FR it still sets loading state to -1: https://github.com/i18next/i18next/blob/master/src/BackendConnector.js#L94 |
|
I upgraded this morning to i18next@18.0.1 and it's fixed. Thanks! |
|
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 “ There are many ways to help this project |
|
i18next 19.0.1 same false warnings. |
|
@zmnv are you sure they are false warnings...? If so please provide a codesandbox for reproduction |
|
Web CRA
React Nativehttps://gist.github.com/zmnv/53729aace40af35e429e10691ee9e218 Actually I need to use i18next with React Native. All time I get warnings, BUT I see translated strings in render(); Open Screen with HOC also used with What am I doing wrong?PS: I try to copy your examples from https://github.com/i18next/react-i18next/blob/master/example/react-native/App.js. Please update packages. Also I see that warnings... |
|
@zmnv there is a) no language set and b) the react-native sample is very basic working on passed in resources on init... |
|
@jamuhl ooohhhhh, I thought When I added it's worked without false warnings. thank you! |
|
@jamuhl not sure if this is documented somewhere, I ran into the same scenario. Using |
|
@andresilveirah honestly I'm not sure where to add this in the docs - for people running into this...thought it's rather logical you got to set |
|
@jamuhl you might be right, maybe it should be straight forward but maybe not |
|
I have a use case where this false warning might still be present, my I have put my code using the |
|
Right now, I can patch my code using: This way the warning disappears, but I really think that this case is treated as a false positive by i18next, what do you think? Thanks! |
|
@tonix-tuft if that works - it just avoids the warning - not fixing the problem do you use either Suspense or handle the ready state given by the withTranslation or useTranslation? |
|
@andresilveirah just to come back to your isssue - a warning was added for the case no detector was used and no lng set... |
|
That's really cool @jamuhl , appreciate the effort. |
|
@jamuhl I am using Suspense, yeah, that's a workaround, but I don't see the warning this way... Otherwise is there a way to execute some code using the ready Thank you very much! |
|
@tonix-tuft do you use the backend as is - or add translations partial manually? Must be something special - normally I would expect the i18next.init call to return before the withTranslation/useTranslation get there state set to ready by loading needed namespaces and check for those translations available... There is currently only a few ways I could think of this happening:
Would you be able to produce a codesandbox reproducing this behaviour in your app? That would help a lot... |
|
I am using the XHR backend plugin to load all the translations through AJAX. Yes, I load several namespaces initially:
Because otherwise if I e.g. remove But that's another story. If you look at your fiddle here you should see the warning in the console (I attach a screenshot): https://jsfiddle.net/jamuhl/ferfywyf/ HTML code: JS code: Try to uncomment |
|
When using multiple namespaces in one file like The jsfiddle is old - and suffers an issue...renders initially twice - once on the init callback and once on the languageChanged event coming before init is done: https://jsfiddle.net/jamuhl/ferfywyf/523/ i18next.on('languageChanged', () => {
if (i18next.isInitialized) updateContent();
});would correct that sample - might add a check for isInitialized to the react check - but not 100% that was once there and removed out of a reason... |
|
Guess had todo with https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md#1012 Nope nothing todo with it... |
|
https://github.com/i18next/react-i18next/blob/master/src/useTranslation.js#L42 why does it render and not throw the Suspense on your code? Are you sure you did not set |
|
Yes I am sure, |
|
Anyway, shouldn't |
|
and there you access t to early: i18n.on("languageChanged", lng => {
ref.lng = lng;
// I need to execute some initialization functions which depend on the i18next "i18n" object
// each time the language changes and THE VERY FIRST time
// when the first language is loaded from the backend BUT BEFORE rendering the suspended components.
// The namespace is loaded at this point,
// and both "thousandSeparator" and "decimalSeparator" are translated correctly,
// but i18next complains about them not being loaded (though, they are)
// and outputs the warning in the console:
//
// i18next::translator: key "format.thousandSeparator" for namespace "common"
// for languages "en" won't get resolved as namespace was not yet loaded...
//
const thousandSeparator = i18n.t('format.thousandSeparator')
const decimalSeparator = i18n.t('format.decimalSeparator')
Both `thousandSeparator, decimalSeparator`
initNumberFormatting(thousandSeparator, decimalSeparator)
});change that to: i18n.on("languageChanged initialized",() => {
if (!i18n.isInitialized) return;
ref.lng = i18n.language;
// I need to execute some initialization functions which depend on the i18next "i18n" object
// each time the language changes and THE VERY FIRST time
// when the first language is loaded from the backend BUT BEFORE rendering the suspended components.
// The namespace is loaded at this point,
// and both "thousandSeparator" and "decimalSeparator" are translated correctly,
// but i18next complains about them not being loaded (though, they are)
// and outputs the warning in the console:
//
// i18next::translator: key "format.thousandSeparator" for namespace "common"
// for languages "en" won't get resolved as namespace was not yet loaded...
//
const thousandSeparator = i18n.t('format.thousandSeparator')
const decimalSeparator = i18n.t('format.decimalSeparator')
Both `thousandSeparator, decimalSeparator`
initNumberFormatting(thousandSeparator, decimalSeparator)
}); |
|
I know that
I cannot use I need to set up formatting by executing this code: Before any component using the The only way I found to do it seems to use the following code: i18n.init(...); // Init i18next.
// Registrer "languageChanged" event handler/callback
i18n.on("languageChanged", lng => {
//if (!i18n.isInitialized) return; // Can't use this line because otherwise formatting won't be set on initial rendering when the namespaces for the initial language are loaded.
ref.lng = lng;
//i18n.isInitialized = true; // With this line commented out, i18next outputs the warning, but `i18n.t('format.thousandSeparator')` returns the correct string for the user's language...
const thousandSeparator = i18n.t('format.thousandSeparator')
const decimalSeparator = i18n.t('format.decimalSeparator')
initNumberFormatting(thousandSeparator, decimalSeparator)
});I hope I was clear. Thank you again! |
|
So guess - you can keep your "hacky" way to avoid the warning (knowing what you do - so it does not hurt). Not sure how to avoid this edge case - as there is no way to delay the |
|
I cannot share you the source code, but I can attach a screenshot to make you understand better the issue I am facing. This is the application I am building: The React components that render the percentage values require i18n formatting and the formatting itself depends on the initialized i18next instance (because I need to call e.g. On page load, i18n
.use(initReactI18next)
.use(i18nextXHRBackend)
.use(intervalPlural)
.init({
lng, // A global variable, generated server-side.
fallbackLng: [defaultLng], // Same as "lng".
ns: ["ns1", "ns2", "ns3", ... , "nsN"],
defaultNS: "ns1",
backend: ... // XHR backend configuration
},
() => {
// init callback.
}
);
i18n.on("languageChanged", lng => {
// If I remove this patch, i18next displays the not initialized warning,
// though I suppose that i18next is initialized at this point when it executes this code.
//* Patch
const isInitialized = i18n.isInitialized;
i18n.isInitialized = true;
//*/
// Init i18n formatting. This code will run when the page loads and i18next
// has loaded the translations for the initial language ("lng") downloading
// the files from the backend, as well as when I programmatically call `i18n.changeLanguage("new-LNG")`.
const thousandSeparator = i18n.t('format.thousandSeparator');
const decimalSeparator = i18n.t('format.decimalSeparator');
initNumberFormatting(thousandSeparator, decimalSeparator);
// Resetting `i18n.isInitalized` to its previous value.
//* Patch
i18n.isInitialized = isInitialized;
//*/
});The above code works, and once the page loads and Now, if I move this code: // Init i18n formatting.
const thousandSeparator = i18n.t('format.thousandSeparator');
const decimalSeparator = i18n.t('format.decimalSeparator');
initNumberFormatting(thousandSeparator, decimalSeparator);from the i18n
.use(initReactI18next)
.use(i18nextXHRBackend)
.use(intervalPlural)
.init({
lng, // A global variable, generated server-side.
fallbackLng: [defaultLng], // Same as "lng".
ns: ["ns1", "ns2", "ns3", ... , "nsN"],
defaultNS: "ns1",
backend: ... // XHR backend configuration
},
() => {
// i18next init callback.
const thousandSeparator = i18n.t('format.thousandSeparator');
const decimalSeparator = i18n.t('format.decimalSeparator');
initNumberFormatting(thousandSeparator, decimalSeparator);
}
);
i18n.on("languageChanged", lng => {
// Execute only when the language changes through `i18n.changeLanguage()` while using the app,
// and NOT when the page loads (when `i18n.isInitialized === false`).
if (!i18n.isInitialized) return;
// Init i18n formatting. This code will run ONLY when I programmatically call
// `i18n.changeLanguage("new-LNG")`, and not when the page loads for the first time
// and i18next has loaded the translations.
const thousandSeparator = i18n.t('format.thousandSeparator');
const decimalSeparator = i18n.t('format.decimalSeparator');
initNumberFormatting(thousandSeparator, decimalSeparator);
});With the above code, when the page loads, the formatting is not initialized on time, it's rather initialized too late when the suspended React components have already been rendered, so you can see formatting is missing (in my case, if So the only way to achieve what I want is to use the first option and place all my initialization within the "languageChanged" event callback and setting I hope I was esplicative and clear. Let me know. Thank you very much! |
|
The implementation is suboptimal...taking separators from translations is not the best option...chicken egg problem
Also bind the https://www.i18next.com/overview/api#oninitialized beside language change -> https://github.com/i18next/react-i18next/blob/master/src/useTranslation.js#L42 might work There is no need to explain over and over the #977 (comment) still is valid |
|
Thank you @jamuhl, I got it. I was using This library needs to know the thousand and decimal separator in advance: I took a look at the https://www.i18next.com/translation-function/formatting link you provided and there's a lib called numeral.js which seems to be pretty interesting. But even that library needs to know the separators to use in advance (http://numeraljs.com/#locales): What do you advise in order to format numbers and currency in an i18n format to support all languages? Thank you! |
|
Thank you Jan! No more questions :) |
|
@tonix-tuft hope I was able to help... |
|
Today I modified the code again and here is what I ended up with: This way everything works, thanks again! |
|
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 “ There are many ways to help this project |
|
I'm having the same issue like render is getting loaded before i18n. .init( I'm not really sure what to add in the callback funciton to supress the warnings, please help me out in resolving this issue |
|
You set useSuspense: false and I'm sure you do not handle the ready flag given -> so you render before ready...https://react.i18next.com/latest/usetranslation-hook#not-using-suspense |
|
adding this when i18next is initialized solved the issue : |
|
@andresilveirah ...just make sure you got useTranslation or withTranslation everywhere you use |
|
@tonix-tuft from where you got this method initNumberFormatting? In my case, it always comes undefined. |










Describe the bug
I'm having a warning that I think is a false positive.
I get the thousands of the following warning:
i18next.js:27 i18next::translator: key "xxx" for namespace "translation" 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 think it's a false positive for 3 reasons:
init()before callingReactDOM.render().Before all the warnings, the console prints this:
Occurs in following versions
npm 6.12.0
react-i18next 10.13.2
OS (please complete the following information):
The text was updated successfully, but these errors were encountered: