React-i18next: NextJS example won't Server Side Render after combining "with-apollo" example

Created on 29 Oct 2018  路  16Comments  路  Source: i18next/react-i18next

I've tried to resolve this issue on my own unsuccessfully for literally days now. I set up an isolated repository to demonstrate the issue.

https://github.com/mikepuglisi/next-js-with-apollo-and-i18next

Summary:

When NamespacesConsumer and ApolloProvider are both utilized in _app.js, server side rendering of the Apollo component no longer occurs. You will see the "Loading..." text before the graphql data is presented which indicates that the data is being loaded and rendered client side. I also included a screenshot in the repository to illustrate the issue.

Any assistance would be greatly appreciated. Thank you.

next.js / SSR question

All 16 comments

did you try nesting the consumer inside the apolloprovider?

I did try that.

To double check that it didn't work, I just attempted again under the new branch "3_nesting_reversal"

https://github.com/mikepuglisi/next-js-with-apollo-and-i18next/blob/3_nesting_reversal/pages/_app.js

Well idk...does apollo need to set some initialState? if so you might need to merge that. Honestly would be great if you try to figure out what happens...can't be of much help here (no apollo knowhow)

withApollo does something with getInitialState here

https://github.com/mikepuglisi/next-js-with-apollo-and-i18next/blob/3_nesting_reversal/lib/with-apollo-client.js

I'm new to a lot of this stuff, so I'm grasping at straws really.

I see someone else had an issue merging the two, but they apparently resolved it

https://github.com/zeit/next.js/issues/3779

I think they were merging the older "with-i18next" example that's in the next.js examples though. Maybe I'll try that.

Hopefully someone else already uses NextJS, i18next and apollo and will be able to provide some insight.

next.js passes down information via initialState from server to client.

Both set that - i18next here: https://github.com/i18next/react-i18next/blob/master/example/nextjs/lib/withI18next.js#L30

So you need to merge both to get it work.

I'm trying to apply your advise, but again my lack of experience with these frameworks leaves me spending large amounts of time getting nowhere fast. If you could provide a little more insight on what you mean, I'm sure the end result will be useful for many others going forward.

Note that the function you mentioned above never actually gets hit when ApolloProvider is present.

It isn't clear to me how to "merge both [initalStates] to get it work."

  Extended.getInitialProps = async ctx => {
    console.log('nextjs:getInitialProps');
    const composedInitialProps = ComposedComponent.getInitialProps
      ? await ComposedComponent.getInitialProps(ctx)
      : {};

    const i18nInitialProps = i18nInstance.getInitialProps(ctx.req, reportedNamespaces);

    return {
      ...composedInitialProps,
      ...i18nInitialProps,
    };
  };

I gave you the direction to solve it - merging the initialProps stuff - how to do it...idk...sorry but would take me to much time to digg into that myself (time i don't have). Hopefully someone else can catch up...or try asking for help at stackoverflow.

@mikepuglisi If you expect Apollo to do some data fetching before SSR, you need to set that up inside getInitialProps. NextJs and Apollo should work just fine together and this is a question that absolutely belongs on StackOverflow, not a GitHub issue.

RE: "belongs on StackOverflow"

At this point I agree.

RE: "you need to set that up inside getInitialProps"

The with-apollo example (and my repo example) does ssr requests using solely the Query component from within a child component / page.

Example:

https://github.com/zeit/next.js/blob/canary/examples/with-apollo/components/PostList.js

The Apollo getInitialProps method is applied at the _app.js level by using with-apollo-client.js

See:

https://github.com/zeit/next.js/blob/canary/examples/with-apollo/lib/with-apollo-client.js

https://github.com/zeit/next.js/blob/canary/examples/with-apollo/pages/_app.js

I spent another 5 hours or so trying to merge the getinitalprops as suggested above from with-apollo-client and withI18next.js

https://github.com/i18next/react-i18next/blob/master/example/nextjs/lib/withI18next.js

One of the reason I think I'm having so much trouble figuring out a solution is because the with-apollo-client HOC is applied at the _app.js level while the withI18next.js HOC is applied at the page level. Also, because this entire architecture is new to me.

I can certainly take this to stackoverflow. I'm thinking of phrasing the question in a more generic way...

"How to merge getInitialProps from HOC in _app.js with getInitialProps from HOC called in a page."

Feel free to close this.

If you have an insight based on what I am trying to example and solve I would certainly appreciate it.

I'm not entirely sure what you're saying or trying to accomplish, but in general you can use getInitialProps in any page component with NextJs to delay SSR until you have the data you need. Assuming Apollo's methods return promises, that's pretty much job done.

You shouldn't need to touch withI18next at all. If you're trying to manage translation data with Apollo, that's not something we'd recommend or even be able to give advice on.

Good luck, you can always feel free to email me directly if you'd like advice.

closing this for now - not that we do not want to help - but really not belongs into an issue. Thanks for understanding that we can't solve each coding problem in codebases. Not sure - someone should make a profession out of it -> consulting that does not suck but solves problem 馃

@mikepuglisi After I update react-apollov2.3.0 react-apollo@next, SSR is working
https://github.com/apollographql/react-apollo/pull/2533

I know the issue is closed now, but i struggled with this too. If you did not make it, there is my solution :-)

import { appWithTranslation } from '~/lib/i18n';
import attachGraphqlClient from '~/lib/graphqlClient';

class MyApp extends App {
    render() {
        const { Component, pageProps } = this.props;

        return (
            <Container>
                <Component {...pageProps} />
            </Container>
        );
    }
}

const GraphqlComponent = attachGraphqlClient(() => <div />);
const TranslatedComponent = attachGraphqlClient(() => <div />);

const ComposedMyApp = compose(
    attachGraphqlClient,
    appWithTranslation,
)(MyApp);

ComposedMyApp.getInitialProps = async (ctx) => {
    return {
        ...(await GraphqlComponent.getInitialProps(ctx)),
        ...(await TranslatedComponent.getInitialProps(ctx)),
    };
};

export default ComposedMyApp;

Hey, @jandolezal71, I am struggling with the same issue. Please tell from where did you get ~/lib/i18n?

Was this page helpful?
0 / 5 - 0 ratings