Hello.
First of all thank you for this really cool project 馃崻
I am having a hard time making SSR work with this plugin and Apollo Client, following the official example.
I created the HOC for Apollo and then in my _app.js I am doing export default appWithTranslation(withApollo(MyApp)).
Still when running getDataFromTree the HOC for Apollo complains that the router is missing. I think that might be due to the fact that here the router is not provided to the wrapped _app.
I edited the code locally to add the router in the HOC and then I had issues with the withNamespaces complaining about i18nOptions missing during some render.
The main thing is that client side render works, but not the SSR.
I am missing something ?
I put together a simple Sandbox to show the issue https://codesandbox.io/s/3422zvo61q
(you may need to clone this, cannot have it work on the Sanboxsite 馃 )
Thank you for your help.
Hi @nico29, I think you need to convert that CodeSandbox into a "container" project so that it can execute Node code.
In general it might be true that we should spread the remaining object out and pass it into the getInitialProps calls. I've done that with 24f5d6a and just released v0.12.1. Can you try that out?
Thank you @isaachinman for the uber quick answer !
I installed the latest version (0.12.1) and now I got the issue I mentioned regarding the i18nOtions.
Here is the stacktrace:
react-i18next:: You will need pass in an i18next instance either by props, using I18nextProvider or by using i18nextReactModule. Learn more https://react.i18next.com/components/overview#getting-the-i-18-n-function-into-the-flow
Error while running `getDataFromTree` TypeError: Cannot read property 'wait' of null
at NamespacesConsumerComponent.render (/Users/nicolasmarien/Projects/gymlib/hades/node_modules/react-i18next/dist/commonjs/NamespacesConsumer.js:213:33)
at processChild (/Users/nicolasmarien/Projects/gymlib/hades/node_modules/react-dom/cjs/react-dom-server.node.development.js:2861:18)
at resolve (/Users/nicolasmarien/Projects/gymlib/hades/node_modules/react-dom/cjs/react-dom-server.node.development.js:2714:5)
at ReactDOMServerRenderer.render (/Users/nicolasmarien/Projects/gymlib/hades/node_modules/react-dom/cjs/react-dom-server.node.development.js:3098:22)
at ReactDOMServerRenderer.read (/Users/nicolasmarien/Projects/gymlib/hades/node_modules/react-dom/cjs/react-dom-server.node.development.js:3057:29)
at renderToStaticMarkup (/Users/nicolasmarien/Projects/gymlib/hades/node_modules/react-dom/cjs/react-dom-server.node.development.js:3539:27)
at process (/Users/nicolasmarien/Projects/gymlib/hades/node_modules/react-apollo/react-apollo.umd.js:129:24)
at process.internalTickCallback (internal/process/next_tick.js:77:7)
You have not declared a namespacesRequired array on your page-level component: undefined. 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
Also when I view source for my page, here is what I got: empty SSR content.
Also I am facing the same empty SSR content when running the exemple from this repo.
聽 | <!DOCTYPE html><html><head><meta charSet="utf-8" class="next-head"/><link rel="preload" href="/_next/static/development/pages/index.js" as="script"/><link rel="preload" href="/_next/static/development/pages/_app.js" as="script"/><link rel="preload" href="/_next/static/development/pages/_error.js" as="script"/><link rel="preload" href="/_next/static/runtime/webpack.js" as="script"/><link rel="preload" href="/_next/static/runtime/main.js" as="script"/><style data-styled="" data-styled-version="4.1.3">
-- | --
聽 | /* sc-component-id: sc-global-4144658031 */
聽 | body{margin:0;padding:0;}</style></head><body><div id="__next"></div><script src="/_next/static/development/dll/dll_9fa2600ee39173e21395.js"></script><script>__NEXT_DATA__ = {"props":{"initialI18nStore":{"fr":{"home":{"welcome":"Bonjour de l'application Hades"}}},"initialLanguage":"fr","pageProps":{"namespacesRequired":["home"],"query":{}},"apolloState":{}},"page":"/","query":{},"buildId":"development"};__NEXT_LOADED_PAGES__=[];__NEXT_REGISTER_PAGE=function(r,f){__NEXT_LOADED_PAGES__.push([r, f])}</script><script async="" id="__NEXT_PAGE__/" src="/_next/static/development/pages/index.js"></script><script async="" id="__NEXT_PAGE__/_app" src="/_next/static/development/pages/_app.js"></script><script async="" id="__NEXT_PAGE__/_error" src="/_next/static/development/pages/_error.js"></script><script src="/_next/static/runtime/webpack.js" async=""></script><script src="/_next/static/runtime/main.js" async=""></script></body></html>
I'll try to get that container running ASAP.
Thank you.
Oh, right! Interesting.
This is because apollo is running getDataFromTree, which is similar to our own tree-walking implementation, which I recently abandoned for several reasons. You can read more in #54. Basically, the context is broken (not provided).
I'm not sure if apollo is going to be compatible with react-i18next at all... But I do think other users mentioned that they have projects with this combination.
If you get that CodeSandbox up and running, or alternatively just provide a repo, I can take a look.
@MathiasKandelborg Do you have a working example of next-i18next with apollo?
Hi @nico29! Can you try withApollo(appWithTranslation(MyApp)) instead of appWithTranslation(withApollo(MyApp))? This worked for me.
@kachkaev @isaachinman thanks.
So I tried swapping the two HOC. Now effectively the error does away, but I still have no content in the body. Just the empty next root div.
聽 | <!DOCTYPE html><html><head><meta charSet="utf-8" class="next-head"/><link rel="preload" href="/_next/static/development/pages/index.js" as="script"/><link rel="preload" href="/_next/static/development/pages/_app.js" as="script"/><link rel="preload" href="/_next/static/development/pages/_error.js" as="script"/><link rel="preload" href="/_next/static/runtime/webpack.js" as="script"/><link rel="preload" href="/_next/static/runtime/main.js" as="script"/><style data-styled="" data-styled-version="4.1.3">
-- | --
聽 | /* sc-component-id: sc-global-4144658031 */
聽 | body{margin:0;padding:0;}</style></head><body><div id="__next"></div><script src="/_next/static/development/dll/dll_9fa2600ee39173e21395.js"></script><script>__NEXT_DATA__ = {"props":{"initialI18nStore":{"fr":{"home":{"welcome":"Bonjour de l'application Hades"}}},"initialLanguage":"fr","pageProps":{"namespacesRequired":["home"],"query":{}},"apolloState":{}},"page":"/","query":{},"buildId":"development"};__NEXT_LOADED_PAGES__=[];__NEXT_REGISTER_PAGE=function(r,f){__NEXT_LOADED_PAGES__.push([r, f])}</script><script async="" id="__NEXT_PAGE__/" src="/_next/static/development/pages/index.js"></script><script async="" id="__NEXT_PAGE__/_app" src="/_next/static/development/pages/_app.js"></script><script async="" id="__NEXT_PAGE__/_error" src="/_next/static/development/pages/_error.js"></script><script src="/_next/static/runtime/webpack.js" async=""></script><script src="/_next/static/runtime/main.js" async=""></script></body></html>
here is a sample repo
this commit is showing the swap of HOC
(also the sandbox should be running when manually doing npm start in a console)
@nico29 I don't think I'm going to be able to help with that, it seems like an apollo issue. If you look in the HTML returned, you'll see the initialI18nStore is there and looks correct. Which means next-i18next is doing its job.
@isaachinman okay thanks.
But even if the initialI18nStore is correctly filled, there is no HTML with the content. Am I missing something for this ?
I'll ding into the getDataFromTree
I do have an example, I'm just in the middle of converting everything to hooks before releasing a starter kit. I'm also sick so I mostly do some reading and watching videos.
You know what? I'll take a quick shower to get on top, then I'll release what I've got.
@nico29 From what I can see, the only difference I have when initializing Apollo(running getDataFromTree), is checking for process.node:
const NODE =
typeof 'process' !== 'undefined' &&
process &&
process.versions &&
process.versions.node;
Other than that, my i18n settings are the only difference in the i18n implementation:
const LOCALE_STRUCTURE = '{{lng}}/{{ns}}';
const LOCALE_PATH = 'static/locales';
const DEFAULT_LANGUAGE = 'da';
const OTHER_LANGUAGES = ['en'];
const LOCALE_SUBPATHS = false;
const translation = {
debug: false,
allLanguages: OTHER_LANGUAGES.concat([DEFAULT_LANGUAGE]),
defaultLanguage: DEFAULT_LANGUAGE,
localePath: `./${LOCALE_PATH}/`,
localeSubpaths: LOCALE_SUBPATHS,
};
@MathiasKandelborg Cool, I'll be curious to check out your starter kit.
@nico29 I don't really understand what's going on in your demo repo, but the routes seem to be broken. I'm seeing this: pageProps: { statusCode: 404 }.
@isaachinman yep sorry, a console.log was polluting the output. I dropped it.
@nico29 For some reason, tReady is not true in this app. That's triggering NextStaticProvider to return null. I'll look into it.
@nico29 Check the options table. The default value for defaultNS is "common". Since you don't have a namespace named "common", the server was trying to load it and failing, thus tReady was returning false.
If you don't have a "common" namespace, you need to set your defaultNS to something else. I cloned your repo and set defaultNS to "home" and the error ceased.
Let me know if you have any further questions.
@isaachinman Thank you so much. That solved it all!
Also thanks to @MathiasKandelborg and @kachkaev
Merry Xmas to all :)