1
votes

I'm working on a React-app in which I'd like to use i18next. To do so, I've added i18next and react-i18next to my app and everything seems to work like a charm.

My app uses the BrowserRouter from react-router to switch between various views. When I load the root URL at http://localhost:3000, everything runs like a charm. I can switch pages, which are then translated without any problem. The BrowserRouter pushes URL changes to the browser history so users can use the Back- and Forward-buttons in their browser to navigate. This means that once a user clicks one of the menu items in the app, the URL changes, i.e. from http://localhost:3000 to http://localhost:3000/suppliers.

If I hit refresh after such a change though, a problem occurs: the console shows i18next::translator: missingKey undefined translation and the view is not translated. The same behavior is shown when a redirect from the root URL to a default page is added. The strange thing is that the entire app's root UI (headerbar, sidebar) is translated, it's only the part of the page that is managed by react-router (every component nested within the relevant <Route>) that shows untranslated. This is also only the fact on browser load, so after a full page refresh or after an initial navigation to the page. If I navigate in my app after loading, even navigating to the same view, the translated view is shown instead.

I wrapped everything within my <App>-component in a <Suspense>-block, including the <BrowserRouter>, but the problem still occurs. My JSX-structure looks somewhat like this:

<App>
    <Suspense fallback={<Loader /}>
        <BrowserRouter>
            <SideMenu>
                {/* Translated objects are shown here */}
            </SideMenu>
            <HeaderBar>
                {/* Translated objects are shown here as well */}
            </HeaderBar>
            <Views>
                <Route path="/sample" component={SampleComponent} /> {/* SampleComponent will not be translated after changing language or navigating to `/sample` immediately/by refreshing` */}
            </Views>
        </BrowserRouter>
    </Suspense>
</App>

I'm using a very simple configuration:

import i18n from 'i18next';
import Backend from 'i18next-xhr-backend';
import { initReactI18next } from 'react-i18next';

i18n
  .use(Backend)
  .use(initReactI18next)
  .init({
    fallbackLng: 'nl',
    debug: true,
    interpolation: {
      escapeValue: false
    }
  });

export default i18n;

I found an older issue on GitHub (https://github.com/i18next/react-i18next/issues/322) without a clear solution and for an older version of react-i18next. I'm not entirely sure how to integrate react-router with react-i18next to prevent this behavior.

Edit another strange thing is the fact that a call to i18n.changeLanguage is propagated to every view except the components nested within the <Route>... I think it might be related but I've still been unable to find a solution...

1

1 Answers

0
votes

I haven't found an actual solution for the situation I described, but based on the documentation for the Trans component I switched my views to using t instead of Trans and they started working. As I need no complex formatting for my translated strings this is a nice solution. Another solution would be to wrap a component that needs Trans in the HOC-solution, which seems to work as well.