Hi. The following React i18n example:
https://github.com/i18next/react-i18next/tree/master/example/react
works well by itself, I mean when ran locally using the given steps, but since Suspense is not yet supported by ReactDOMServer on server-side-rendering I was wondering if anyone had any ideas on how this same example would look like if is intended to be SSR, since it is failing on that condition?
On serverside most implementations will use a proper setup using i18next-express-middleware configured to load all languages, namespaces upfront -> therefore not run into the useTranslation, withTranslation run into throwing a Promise to trigger a Suspense
Thanks @jamuhl , I'm trying i18next-express-middleware out on my project, however I'm getting the following issue:

I think perhaps it is because of the latest version I installed using npm ("i18next-express-middleware": "^1.7.1",), that is different from the one used on the examples of i18next-express-middleware ("i18next-express-middleware": "1.0.5", );
you're using this on client?!? if i see the last bit of the printscreen right - "webpack plugin"
the express-middleware is a serverside node.js package...
---> consider using: https://github.com/isaachinman/next-i18next
you're using this on client?!? if i see the last bit of the printscreen right - "webpack plugin"
the express-middleware is a serverside node.js package...
---> consider using: https://github.com/isaachinman/next-i18next
Ok, I'll give it a try, thanks @jamuhl ! :) Since I wasn't involved too deep on the server-side rendering process we're using now, I think probably should've gone for the client side package since the beggining
I also don't understand how this could work? withTranslation and useTranslation both throw to Suspense if translations are loading but Suspense isn't supported for SSR yet (react-dom/server will throw error if you try to renderToString with a <Suspense /> component in tree). Am I to understand that v10 of this library no longer supports SSR until react supports Suspense with SSR?
@nicksrandall Suspense will be only triggered when you render the serverside JSX tree and not all translation files (namespaces) are loaded. If you run into that situation on the server - i would suggest preloading all translations on serverside using preload: ['lng1', 'lng2'] containing all supported languages and ns: ['ns1', 'ns2'] containing all namespaces...
Preloading all translations on serverside is not a bad thing...we do not create a empty i18n instance on request but a clone sharing the translations with the main instance -> so no memory pressure.
Do you have any guidance on how to implement SSR without using express? I used to be able to use loadNamespaces but according to the docs the only way now is to set the i18n instance using i18next-express-middleware?
@odensc there now is a suspense free mode
https://github.com/i18next/react-i18next/issues/735#issuecomment-463572416
not yet had time to document that. sorry
Do you have any guidance on how to implement SSR without using express? I used to be able to use
loadNamespacesbut according to the docs the only way now is to set the i18n instance usingi18next-express-middleware?
Hi @odensc! Currently having same thing on my mind. Did you find any solutions?
@4lph4-Ph4un
react: {
useSuspense: false
}
const i18n = baseI18n.cloneInstance();
i18n.language = getPreferredLanguage(req);
<I18nextProvider i18n={i18n}>
[...]
</I18nextProvider>
const i18nState = await getInitialProps(i18n);
[...]
<script
defer
dangerouslySetInnerHTML={{
__html: `window.__I18N_STATE__=${serialize(i18nState)}`
}}
/>
I had some issues with getInitialProps not working with the XHR backend (because it was synchronous). So, I wrote my own version of it! Along with getPreferredLanguage that the Express backend would normally do for you: https://gist.github.com/odensc/216288159aaa2cb41fc924774fce5859 (TypeScript)
Nice! I'll have a look along that kind of path! :) Seems doable! Thank you very much!
Thanks for the code @odensc . I found i18next-node-fs-backend, and I am using that.
Although I am struggling getting the initial data out of my store. Maybe it's not initialised correctly, or maybe I can't get it out. Which version of i18next are you using? As for me i18n.reportNamespaces does not exist on my i18n object, or in the types.
I even tried simply copying the code here, and this didn't work either. Although I think there is something wrong with my config:
i18next
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// use node-fs instead of xhr backend
.use(nodeFsBackend)
.init({
keySeparator: '__KEY__',
defaultNS: 'translation',
interpolation: {
// react is already safe from xss
escapeValue: false,
},
backend: {
loadPath: path.resolve(__dirname, `/locales/{{lng}}/{{ns}}`),
parse: (data: any) => data,
},
react: {
useSuspense: false,
},
})
Then in my controller I do something like this:
const lang = detectLanguageFromUser(req)
const i18n = i18next.cloneInstance()
i18n.language = lang
await i18n.loadLanguages(lang)
And I am stuck here :D
Hi @bitttttten, I'm not quite sure how to solve your issue. I'm using v17.0.6 and reportNamespaces exists on my i18n instance.
It's just the types that are out of date.. if I use your code with (i18n as any).reportNamespaces.getUsedNamespaces() it works, otherwise TS complains with "Property 'reportNamespaces' does not exist on type 'i18n'.".
Thanks!
I just tell about my case:
1) One of module translate has been skiped on node
2) When some translates are missing react-i18next use suspense.
3) React DOM can`t use suspense and build tree on server
4) For some components I pass translates by a component like <T name="mycomponent.title" />
5) Some components did mount only on client and this was no error but another do crash on server
Just load all i18n resource on server =)
Most helpful comment
@4lph4-Ph4un
I had some issues with
getInitialPropsnot working with the XHR backend (because it was synchronous). So, I wrote my own version of it! Along withgetPreferredLanguagethat the Express backend would normally do for you: https://gist.github.com/odensc/216288159aaa2cb41fc924774fce5859 (TypeScript)