i18next / next-i18next

The easiest way to translate your NextJs apps.
https://next.i18next.com
MIT License
5.53k stars 762 forks source link

react-i18next:: i18n.languages were undefined or empty undefined #374

Closed mehmetnyarar closed 4 years ago

mehmetnyarar commented 5 years ago

Describe the bug

I get the the following error:

[ wait ]  compiling ...
react-i18next:: i18n.languages were undefined or empty undefined

which appears only on the server (I mean in the output of the terminal, it doesn’t appear on the browser console).

Occurs in next-i18next version

"next": "^8.1.0", "i18next": "^17.0.6", "next-i18next": "^0.44.0",

Steps to reproduce

I followed every step described in the readme except keySeparator (because I have keys like Status.ONGOING)

Below is my configuration:

import NextI18Next from 'next-i18next'

const instance = new NextI18Next({
  defaultLanguage: 'en',
  otherLanguages: ['ru'],
  keySeparator: false
})

export default instance

Expected behaviour

This doesn’t look like a critical error, though I’m wondering the cause.

Screenshots

OS (please complete the following information)

Additional context

isaachinman commented 5 years ago

Are you sure keySeparator: false is a valid config option? Regardless, if I add that single line to the simple example, I do not see this error.

Please provide reproducible repo.

JeremieLeblanc commented 5 years ago

I believe I'm getting the same error when using i18n.language for a select value. The value is undefined on the server and correct on the client, so it flickers on load.

isaachinman commented 5 years ago

Does anyone have a reproducible example?

shaomingwei commented 5 years ago

I have the same problem,Have you solved it?

mehmetnyarar commented 5 years ago

@isaachinman Here is the repo.

You’ll see a warning initially

You have not declared a namespacesRequired array on your page-level component: ErrorPage. This will cause all namespaces to be sent down to the client, possibly negatively impacting the performance of your app. For more info, see: https://github.com/isaachinman/next-i18next#4-declaring-namespace-dependencies

And then

react-i18next:: i18n.languages were undefined or empty undefined

I also added pages/—ERROR—, which when you rename to _error.tsx, will create a custom error page. ~When it exists, the error goes away.~

In my actually project, I have error page and namespacesRequired is set in getInitialProps in every pages, yet error is still there.

isaachinman commented 5 years ago

@mehmetnyarar I have cloned your repo and run it. I do see the namespacesRequired warning, but that is expected.

I do not see the i18n.languages were undefined warning.

Does anyone have a reproducible example?

deemaagog commented 5 years ago

Does anyone have a reproducible example?

I'm getting this warning when just running simple example (build & start)

"next": "^8.1.0", "i18next": "^17.0.6", "next-i18next": "^0.45.0"

isaachinman commented 5 years ago

@deemaagog I cannot reproduce that either. Can you zip your directory, including node_modules, and send it to me?

mslepcevic commented 5 years ago

I also have this error in a ts project with a custom server, but only in this case:

  1. dev server started with a watch service to reload on code changes to .ts files, with hot reload for .tsx files
  2. a page is open in the browser
  3. save a change to a .tsx file which triggers a recompile
  4. during the recompile, a request for the hot reload module comes in (at least it looks like it does, not entirely sure how that works), results in a 404, which triggers the compilation of the _error page (makes no difference if it's a custom or default.one)
  5. the missing lang message is shown, and common.missing.json gets generated with the error page translations in it (the custom error page is exported and used with the translation wrapper function, and works in 6 below)
  6. when producing a real 404 error by visiting a non-existing page in the browser (both with SSR, and client side navigation), everything works normally

Sometimes, the recompile finishes before the hot module request, and the error page doesn't get generated, and everything is ok, but that might be a 1 out of 10 occurrence.

Using next 8.1.0 and ni18n 0.44.0

isaachinman commented 5 years ago

@mslepcevic Thanks for that information.

@mehmetnyarar Is this a dev-only error, or are you experiencing problems in production? Sounds like this could be a userland dev setup issue.

mslepcevic commented 5 years ago

@isaachinman Just to add that everything worked ok with my setup with next-i18next v0.41.0.

And the HMR request comes in because of the page that's opened in the browser and wants to reload upon saving a file.

WardVH commented 5 years ago

I'm also experiencing the same issue, even in production. It happens on server and browser.

I haven't had the time yet to create a reproducible repository tho. I found this: https://github.com/i18next/i18next/issues/948

I can recall that i've only seen the warning when using the following setup to determine the language:

const currentLanguage = typeof req === "undefined" ? i18n.language : req.language; (in _app.js && _document.js).

Could it be that it's sometimes not waiting for the response and thus triggers the warning?

deemaagog commented 5 years ago

@deemaagog I cannot reproduce that either. Can you zip your directory, including node_modules, and send it to me?

Here is a zip

isaachinman commented 5 years ago

Thanks @deemaagog I've finally seen this reproduced. It's coming from react-i18next's hasLoadedNamespace function.

I will dig into this now, but it looks like a harmless warning, unless I'm mistaken.

isaachinman commented 5 years ago

So although I saw the error one time, I cannot reproduce it reliably and have not seen it since then. If this is a race condition, I'm not sure where it is.

It seems like this would be caused by a call to useTranslation before the i18next express middleware has set up i18n.languages.

urielscola commented 5 years ago

@isaachinman first of all, thanks for the plugin :) I had the same problem described here, here is the repo Hope it helps to debug

isaachinman commented 5 years ago

@urielscola Multiple problems with your repo which are unrelated:

  1. You're using next start instead of a custom server, which is a requirement
  2. You're not pointing your build script to your src dir

That said, even if I run yarn dev, the server never comes online.

urielscola commented 5 years ago

@isaachinman thanks, you were absolutely right. I fixed those problems and now it is working

ilhammeidi commented 5 years ago

I got the same issue because I just use footer:description only, but I called both common and footer,

<Typography variant="h5" align="center" color="textSecondary" paragraph> {t('footer:description')} </Typography>

export default withTranslation(['footer', 'common'])(Landing);

I tried to remove 'common. But the issue still happen. I'm not sure why the 'common' translation is a must. So I added another text with translation:common in my page.

<Typography component="h1" variant="h2" align="center" color="textPrimary" gutterBottom> {t('common:h1')} </Typography>

Then the issue is resolved.

isaachinman commented 5 years ago

@ilhammeidi Can you please provide a reproducible repository?

ilhammeidi commented 5 years ago

@ilhammeidi Can you please provide a reproducible repository?

Here's my file and repo https://github.com/ilhammeidi/luxi-react-starter/blob/master/pages/index.js

I'm still testing about "react-i18next:: i18n.languages were undefined or empty undefined" message that sometime show in console. After ctrl+shit+r in chrome and restart server, it's gone already.

isaachinman commented 5 years ago

Okay, please let me know if you discover a reliable way to reproduce it.

qlaffont commented 5 years ago

Hi, Same error for me. I don't understand why :/. Zip : http://s000.tinyupload.com/index.php?file_id=28449173765932552030

ricardo-cantu commented 5 years ago

I see 2 possible issues

isaachinman commented 5 years ago

@ricardo-cantu Thanks for your input. Indeed it'd be good if we can await the promise returned by init, but that could end up being a bit tricky - I would appreciate any/all suggestions in regards to that.

Can you explain your second point in more detail? The mysterious i18n.languages were undefined error is coming specifically from react-i18next.

ricardo-cantu commented 5 years ago

@isaachinman Thanks for the awesome work you've done with this library. I wrote my own implementation in typescript based on your work (I left out several things I didn't need)

isaachinman commented 5 years ago

nextApp.prepare()

I'm hesitant to go down this road, as we are really trying to get closer to serverless support.

As for the second point, req.i18n is actually a clone of your main i18n instance. This is the expected pattern with the i18next express middleware.

ricardo-cantu commented 5 years ago

You can simply show an example of wrapping the application with a top level function. There's already an example of index.ts -> server.ts somewhere in next.js examples.

import {application} from './app.ts'  

application();  

app.ts  
async () => {  
}

When you say serverless, do you mean no node server like express?

gtolarc commented 5 years ago

@isaachinman I have the same problem. The current flow seems to have the problem that defaultLanguage is not assigned to initialLanguage in the first appWithTranslation-getInitialProps server rendering. I have confirmed that warning is not generated in react-i18next when hard-coding the initialLanguage value.

isaachinman commented 5 years ago

@gtolarc That's very helpful, thank you! If I set initialLanguage to null manually, I see this error on the client side, however I do not see it in SSR. Do you have a way of reproducing on the server side?

isaachinman commented 5 years ago

Ah, if I comment out this line, I can reliably reproduce this server side.

So, that seems to point to an issue with the lng-from-req util.

gtolarc commented 5 years ago

@isaachinman It seems like there was a my misunderstanding. I thought this library was not designed with the nextI18NextMiddleware middleware as mandatory. So I used your library without a custom server, and the lack of an i18n instance in req occured.. It seems to be the main reason for all of those problems, at least in my case.. Whatever, I think you can change to support ssr without middleware. I think it is necessary since the latest version of nextjs has been able to do dynamic routing without a custom server and admitted that the design as a custom server is not good, many people will use nextjs in the future without a custom server.

isaachinman commented 5 years ago

@gtolarc The middleware is mandatory. Support for serverless is being tracked with #274. Let's keep this on topic, please.

gtolarc commented 5 years ago

@isaachinman I know that serverless support will need more ideas because there is a problem to service static resources. but it seems possible to remove middleware without serverless support.

If the above is implemented, there should be a logic change in the part that judges the initial setting, and the problem of the current thread will also be related.

murat-mehmet commented 5 years ago

I had the same issue on first page load efter every npm start. Added the following in i18n.ts:

NextI18NextInstance.i18n.languages = ['en', 'tr', 'fr'];

Seems like it suppressed the warning.

isaachinman commented 5 years ago

current thread will also be related

Current bugs are not related to proposed features which haven't been implemented yet.

Perhaps @jamuhl might be able might be able to share some of his wisdom on why the i18n instance isn't initialising properly, and/or why there might be a race condition here?

jamuhl commented 5 years ago

@isaachinman from reading my guess is the warning comes from the .init call of the "main" i18next instance --> language is detected per request, therefore the detector fails on the main instance as it can't pass req to the detection function resulting in an undefined lookup (but should set it to fallbackLng normally...not sure why this does not happen here).

Or any direct call to i18n.t before init was done...eg. by not using the t function passed from I18nextProvider (in case of serverside)

lechip commented 5 years ago

I had this problem and was caused on a bump from 0.37.0 to 0.51.1. The issue was that on the options when isntantiating the NextI18Next object, I had a backend node that did not explicitly differentiated the server (static path) from the client (request). Maybe this is useful?

truongtx9 commented 5 years ago

I had fix this issues, you can add lng: 'en' in file i18n.js.

import NextI18Next from 'next-i18next'

const NextI18NextInstance = new NextI18Next({ defaultLanguage: 'en', lng: 'en', otherLanguages: ['de'] });

/ Optionally, export class methods as named exports / export const { appWithTranslation, withTranslation, i18n } = NextI18NextInstance

export default NextI18NextInstance

isaachinman commented 5 years ago

@truongtx9 That will most likely break language detection.

ghost commented 5 years ago

@isaachinman Here is the repo with reproducable state: see branch bug/i18n-languages-empty in https://github.com/keethu24/next-getting-started/tree/bug/i18n-languages-empty

Install deps and then run npm run dev.

nathan818fr commented 5 years ago

This server-side error is due to next-i18next that does not pass a callback to i18next.init. https://github.com/isaachinman/next-i18next/blob/680a55be85ff757610ea28b144f103578f432b23/src/create-i18next-client.ts#L28

So it don't wait for a complete i18next initializtion and i18next may not be fully initialized when first used.

A temporary fix is to set initImmediate to false which cause a sync loading of i18next (see https://github.com/i18next/i18next/blob/527003960b5f3b83162df2f9492353be7cae5fd6/index.d.ts#L384):

const i18nInstance = new NextI18Next({
    defaultLanguage: 'en',
    [...]
    initImmediate: false,
});
isaachinman commented 5 years ago

@nathan818fr Thanks, that sounds right. We've talked about this before in other issues. It's a race condition, but should only affect people running ASGs where traffic hits a service immediately after coming online.

I don't think we should expect users to await the class constructor or have to pass a callback. It seems like shifting this initImmediate approach into the next-i18next would be an appropriate fix.

isaachinman commented 5 years ago

Fix released with v1.1.0. Please upgrade and let me know if you still experience the bug. Thanks everyone for your patience!

shakesBeardZ commented 5 years ago

@isaachinman still the same after upgrading

isaachinman commented 5 years ago

@shakesBeardZ What version are you on, and do you have steps to reproduce?

nathan818fr commented 5 years ago

It happens to me less often than before, but yes sometimes it happens again :/ In i18next, even when initImmediate is set to false, I18n.changeLanguage is called... and it seem async... https://github.com/i18next/i18next/blob/df4d486dec997fb785e71e2b3965c128f75834f0/src/i18next.js#L125

gtolarc commented 5 years ago

@isaachinman Even with the latest version, problems always occur during development mode HMR. This may not be a real problem in production, but if you get error messages frequently during development, it's likely that developers may misunderstand this library is not stable. I hope you solve this problem :)

qlaffont commented 5 years ago

For me I have fix this error with this :

/* eslint-disable object-curly-newline */
import NextI18Next from 'next-i18next';

const nextI18nOptions = {
  defaultLanguage: 'en',
  otherLanguages: ['fr'],
};
const languages = nextI18nOptions.otherLanguages;
languages.push(nextI18nOptions.defaultLanguage);

const NextI18NextInstance = new NextI18Next({ ...nextI18nOptions });

if (NextI18NextInstance && NextI18NextInstance.i18n && !NextI18NextInstance.i18n.languages) {
  NextI18NextInstance.i18n.languages = languages;
}

export default NextI18NextInstance;

const actualLanguage = NextI18NextInstance.i18n.language || nextI18nOptions.defaultLanguage;

/* Optionally, export class methods as named exports */
export const { appWithTranslation, withTranslation, i18n, Link, Router } = NextI18NextInstance;
export { languages, actualLanguage };
StarpTech commented 5 years ago

I also faced with the issue regularly but I can't reproduce it. I would reopen the issue.