i18next / next-i18next

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

appWithTranslation is causing the React state to not consist when doing client-side page navigation. #2259

Closed pgburrack closed 3 months ago

pgburrack commented 3 months ago

🐛 Bug Report

Wrapper _.app.js with the appWithTranslation HOC is causing the React state to not consist when doing client-side page navigation.

To Reproduce

I created this repo with a simple example that you can clone and try: https://github.com/pgburrack/next-i18next-issue

In the example repo I created a DummyProvider with the initial state.

const [state, setState] = useState({
    a: null
  });

Steps to reproduce:

  1. start repo by running npm run dev + open http://localhost:3000/
  2. Open console developer tools. I would expect to see:
{a: null}
{a: null}
{a: 'foo'}
{a: 'foo'}

👆 this is the state that is in the DummyProvider.

  1. Click on "Go to about page" (while keeping the console open) image

You will see that the state in DummyProiver is initiated again.

{
  a: null
}

Note: if you comment out appWithTranslation and just export the App component. you will see that the state is being kept on client-side navigation.

Expected behavior

When navigating to the /about page i would expect the DummayProvider to be

{a: 'foo'}

Your Environment

P.S i found that if I pass options to appWithTranslation it will work as expected.

Example:

export default appWithTranslation(MyApp, {
  i18n: {
    defaultLocale: DefaultLocale,
    locales: SupportedLocales,
  })

The docs are not saying to do that as well, as we have that information in next-i18next.config.js so i am not sure why i would need to do that.

I suspect that the following line of code is causing the issue

https://github.com/i18next/next-i18next/blob/master/src/appWithTranslation.tsx#L120

    return i18n !== null ? (
      <I18nextProvider i18n={i18n}>
        <WrappedComponent {...props} />
      </I18nextProvider>
    ) : (
      <WrappedComponent key={locale} {...props} />
    )

I saw that when doing the navigation will disappear.

Could use help with this 🙏

pgburrack commented 3 months ago

I also noticed that the issue is only happening when one page is translated and the other is not.

adrai commented 3 months ago

I also noticed that the issue is only happening when one page is translated and the other is not.

That's exactly the problem... if a page is not using next-i18next, there is nothing that will correctly initialize next-i18next... So you can either use next-i18next on every page or pass the nextI18nextConfig config via appWithTranslation... (btw: you don't need to create a new "empty" config, you can just pass in the original config)

import nextI18nextConfig from '../../next-i18next.config';
//...
export default appWithTranslation(MyApp, nextI18nextConfig);
pgburrack commented 3 months ago

Hi @adrai

Thanks for the quick reply and the suggestion!

To give you some context on my original issue which made create this example repo and this Github issue.

I started to add next-i18next to a few page in an existing NextJs website that has a lot of pages. I started seeing bugs which made me start investigate and find the issue with next-i18next.

I am wondering if there is a way next-i18next can always make sure to wrap an app with the <I18nextProvider i18n={i18n}> provider and either default i18n to an empty object to avoid react state from getting cleared? not sure what are the implications of that?

OR

update the README/docs to mention the issue here and how to solve it?

basically to make sure other people are not facing the same issue 😃

Maybe something like:

Partially translated website

OR

Start using next-i18next Incrementally

If you want to only use next-i18next on some pages make sure to do the following

import nextI18nextConfig from '../../next-i18next.config';
//...
export default appWithTranslation(MyApp, nextI18nextConfig);
adrai commented 3 months ago

Feel free to provide a PR to update the readme

pgburrack commented 3 months ago

@adrai sure 😄

just confirm: you don't think it is feasible or good idea to always wrap the app with a Provider? and if no, why? 🙏

adrai commented 3 months ago

no, we tried this in the past, and it resulted in other errors

pgburrack commented 3 months ago

Opened a PR https://github.com/i18next/next-i18next/pull/2260