React-i18next translation only after component re-rendered

Viewed 32

I have a page using Next and react-i18next of both English and French.
Now the issue is if I have set language to Frn and refresh, it still show english contents.
I found two wired things:

  1. If i remove SSR contents, ie, getServersideProps, french translation would show up.
  2. Anything that would trigger a component re-render would update the translate. (eg: if a child is re-rendered, the child would have frn, but all parents still in english)

codes:
pages/.../indexs.tsx

export const getServerSideProps: GetServerSideProps = async ({ req }) => {
  // async requests
  return {
    props: { ...props },
  };
  return {
    props: {...},
  };
};

export default function Page(props) {
  const { t } = useTranslation();
  // other hooks
  return (
    <>
      <h2>{t('page title') + temp}</h2>
      // ... other components
    </>
  )
}

initi18n.ts:

export const initI18n = async () =>
  await i18n
    .use<ThirdPartyModule>(initReactI18next)
    .init({
      resources: {
        en: {
          common: commonEn,
        },
        fr: {
          common: commonFr,
        },
      },
      ns: ['common'],
      defaultNS: 'common',
      lng: 'en',
      fallbackLng: 'en',
      interpolation: {
        escapeValue: false,
      },
      debug: true,
    });

_app.tsx(root component):

initI18n().then(
  () => undefined,
  () => undefined,
);

function MyApp({})

i18n debug log:
i18next: languageChanged en
i18next: initialized {...}
i18next::translator: missingKey (some english keys are missing, which should be fine)
i18next: languageChanged fr

My own investigate is following:
In one useEffect, it get selectedLang from local storage (or default to english) => and call i18n.changeLanguage(currLang). Thats why in the log, it first set to eng and then frn.
But I cannot figure out why it didnt render the changes after setting lang to frn.

Tried a codesandbox but failed. Any help would be appreciated.

1 Answers

Based on my research so far, this behavior is "as expected".
The first question was why not use next-18next, and the reason is we cannot add locale into url, and i cant find a solid example in the "traditional way".
So it is hard to switch to next-i18next. And based on Nextjs's logic, it will show server render until client re-render being triggered. the And using a language detector will cause next render conflict.
Previously we had a useeffect function in header component, so turned out only the header got translated, except for the static page. Now I just move the sideeffect to the base component, children level of the i18n provider. So the rerender effect on the entire page rather than certain components.
Well this is not the best solution but at least works so far.

Related