-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[error/warning]: You will need pass in an i18next instance by using initReactI18next #876
Comments
What happens...the console.log statement does not come for free blocking execution below - which gives i18next the needed time to initialize (that's my guess). So what basically happens as you do not use Suspense - and my guess you also do not handle You might set |
thanks @jamuhl, I wasn't aware of the |
Unfortunately it didn't bring me much further, I am starting to wonder if webpack is just ignoring the whole I placed a console.log in the The error still shows, despite adding If I run it locally, edit I don't know why I am telling you all this :-D, I'll close the issue, thanks for your time |
sometimes it helps to talk about the issue - or in the worst case some distance to the problem and solutions come up |
on the off chance that someone else runs into this, the error had nothing to do with i18next, and it was merely a faulty webpack setting. In package.json we had:
the issue got resolved by changing it into:
|
In my case, the warning appeared during jest tests. For the time being, I've gotten around it by redefining const { t } = jest ? {t:s=>s} : useTranslation(); |
@devboell Thanks, you've saved me what would have probably been a few hours of hair-tearing. |
For getting rid of Jest warnings easier than modifying components themselves: jest.mock('react-i18next', () => ({
useTranslation: () => ({t: key => key})
})); |
I am still getting a warning about i18nextReactModule in my App.test.js. I had more errors but researched and found this thread and added I18nextProvider to fix a few of them. Below are the files I am working with. Any help would be appreciated. i18n.js
App.js
App.test.js
UseTranslation.js
UseTranslation.test.js
|
@DevScissors where do you import the i18n.js?!? The implementation is not: Get i18n from useTranslation and pass it to the I18nextProvider. The I18nextProvider would get it from the import and would be the most outer Element (before getting t, i18n from useTranslation). The Provider is only needed if not calling
|
@jamuhl Thank you, that fixed the warnings! I am still brand new to using i18next and pretty new to jest so this has been a bit of a rough ride. Thanks for the quick response too! |
Extending it for the case of handling objects:
It'd be:
|
For those who use Trans component, it makes sense to mock it as well: jest.mock("react-i18next", () => ({
useTranslation: () => ({ t: key => key }),
Trans: ({ children }) => children
})); Otherwise there will be an error of "Invariant Violation: Element type is invalid". |
Can someone explain where (which file) we need to write 👇
Do we need to have it within our test.js file or component.js file? |
You can place it at the top of the file right after file imports and before the describe block |
jest allows to define a set of setup files to handle this kind of stuff In create-react-app this file is called setupTests.js beforeEach(() => {
jest.mock('react-i18next', () => ({
useTranslation: () => ({ t: (key: string) => key })
}));
}); |
Using Jest with next and next-i18next My solution was put this in setupTests.js if it helps: jest.mock('./i18n', () => ({
withTranslation: (i18nFile) => (component) => {
const i18nJson = require(`./public/static/locales/en-US/${i18nFile}.json`)
return (props) => component({t: key => i18nJson[key], ...props})
},
i18n: {
language: "en-US"
}
}));
jest.mock("next/config", () => {
return {
default: jest.fn(() => {
return { publicRuntimeConfig: { localeSubpaths: {} } }
})
}
}) |
can't remember where I found this but it works really nice const React = require('react');
const reactI18next = require('react-i18next');
const hasChildren = (node) => node && (node.children || (node.props && node.props.children));
const getChildren = (node) =>
node && node.children ? node.children : node.props && node.props.children;
const renderNodes = (reactNodes) => {
if (typeof reactNodes === 'string') {
return reactNodes;
}
return Object.keys(reactNodes).map((key, i) => {
const child = reactNodes[key];
const isElement = React.isValidElement(child);
if (typeof child === 'string') {
return child;
}
if (hasChildren(child)) {
const inner = renderNodes(getChildren(child));
return React.cloneElement(child, { ...child.props, key: i }, inner);
}
if (typeof child === 'object' && !isElement) {
return Object.keys(child).reduce((str, childKey) => `${str}${child[childKey]}`, '');
}
return child;
});
};
const useMock = [(k) => k, {}];
useMock.t = (k) => k;
useMock.i18n = {};
module.exports = {
// this mock makes sure any components using the translate HoC receive the t function as a prop
withTranslation: () => (Component) => (props) => <Component t={(k) => k} {...props} />,
Trans: ({ children }) =>
Array.isArray(children) ? renderNodes(children) : renderNodes([children]),
Translation: ({ children }) => children((k) => k, { i18n: {} }),
useTranslation: () => useMock,
// mock if needed
I18nextProvider: reactI18next.I18nextProvider,
initReactI18next: reactI18next.initReactI18next,
setDefaults: reactI18next.setDefaults,
getDefaults: reactI18next.getDefaults,
setI18n: reactI18next.setI18n,
getI18n: reactI18next.getI18n,
}; |
Thanks for the example @FDiskas.
It's from here https://github.com/i18next/react-i18next/blob/7cfab9746b3ccc6f833cd9c892e7c3c804944a5e/example/test-jest/src/__mocks__/react-i18next.js. |
jest.mock('react-i18next', () => ({ Is not helping |
I updated my answer. Just create that file under mocks directory. Should work |
create a import '@testing-library/jest-dom';
jest.mock("react-i18next", () => ({
useTranslation: () => ({ t: (key: string) => key }),
})); |
Maybe useful for others, there are some good infos describing how to setup the test properly at: I personally don't want stubbing, and there is an example for that. |
Maybe i'm overlooking something here, but for me the fix was a mere one-liner. Simply added setupFiles: ['web/src/i18n'], to the Of course, one could define a separate file initialization script specifically for the test environment and/or write a hook-mock to be executed before each test. The latter would then be configured to be made available to every test with |
Sorry to bother, I posted this question first on SO
I am using i18next and react, and locally it works as expected, but when I deploy on Surge I always get this error:
react-i18next:: You will need pass in an i18next instance by using initReactI18next
They way I implemented it is almost identical to the react-i18next documentation.
main.jsx
services/app/i18n.js
The thing I don't understand is that when I console.log the
i18next
variable inmain.jsx
, it prints out the initialised object, and it works when deployed. If I don't log it, it just shows the error and the translations are not available in the app.I am using these versions:
It is going to be tricky for me to make a small repo that reproduces this error. For now I am hoping on clues and suggestions so I can investigate further.
The text was updated successfully, but these errors were encountered: