next-translate icon indicating copy to clipboard operation
next-translate copied to clipboard

getInitialProps dont run when using custom server and custom _app withTranslate

Open wilsonneto-dev opened this issue 4 years ago • 15 comments

Good morning, I'm using custom server and custom _app, wrapping my _app with withTranslate... But when I do this my pages getInitialProps stop running... Simply dont run anymore...

can you help me?

My code is in this repo to help you with your tests, thanks so much (you can check the error running "npm run dev", dont throw error, but dont execute the getInitialProps): https://github.com/wilsonneto-dev/NextJS_Translate_with_getInitialProps

My Server: image

My custom app: image

My page that the getInitialProps isnt running properly: image

Can you help us?

Thanks so much!

wilsonneto-dev avatar Jul 09 '20 12:07 wilsonneto-dev

But if I replace this line with the other line the translate dont run but the getInitialProps run... (This is the _app.tsx file):

image

wilsonneto-dev avatar Jul 09 '20 12:07 wilsonneto-dev

Can you provide your next version, next-translate version, and your i18n.json? It would be great in order to try to reproduce it. Or a reproducible example...

Your shared code apparently looks correct.

aralroca avatar Jul 09 '20 12:07 aralroca

Thanks man, bellow my libraries versions:

image

image

And my i18n configuration file is:

image

I home this help... but if you clone my repo and run "npm run dev" you will see the issue/error happening: https://github.com/wilsonneto-dev/NextJS_Translate_with_getInitialProps

Let me know if you need mor informations please. Thanks so much.

wilsonneto-dev avatar Jul 09 '20 13:07 wilsonneto-dev

@wilsonneto-dev thanks so much to share your code. This was very useful, it helped us too much! We found a bug when the _app.js don't have a getInitialProps.

This will be released on 0.17.2. However, I already pre-released to 0.17.2-canary.5! Can you confirm that is fixed in your case? 🙌

Thank you!!

aralroca avatar Jul 09 '20 14:07 aralroca

Good morning @aralroca , perfect, the pre-relase solved our problem. 🙌

Thanks so much! It will help us a lot!

wilsonneto-dev avatar Jul 10 '20 14:07 wilsonneto-dev

Hi still seeing this with next-translate 1.0.1, next.js 10.0.4. My setup involves a custom _app and a custom server. I'm trying to use the withTranslation HOC with my _app component so that I can access the i18n.lang attribute to pass the current locale to antd components. Should custom apps use appWithI18n?

I have opted out of next.js Automatic Static Optimization by defining getInitialProps in my _app as well as _document. I do this since I need every request to go through my server.

EDIT: For anyone else that stumbles here a solution for my case was to use Next.js 10's internationalized routing features and extract locale information from router like so:

class MyApp extends App<Props> {
  static async getInitialProps({ Component, ctx, router }: any) {
    let pageProps = { locale: router.locale };

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    return { pageProps };
  }

  render() {
    const { Component, pageProps, apollo, locale } = this.props;

    return (
      <ApolloProvider client={apollo}>
        <ConfigProvider locale={locale === "en" ? enUS : fiFI}>
          <Component {...pageProps} />
        </ConfigProvider>
      </ApolloProvider>
    );
  }
}

rriski avatar Dec 30 '20 21:12 rriski

@rriski is it already happening to you on 1.0.2-canary.2 prerelease?

If it still happens to you, can you share more details about your problem? if you have a reproducible example it would be great 🙏 Thanks!

aralroca avatar Dec 30 '20 23:12 aralroca

I tried 1.0.2-canary.2 now it but it completely broke my translations, no namespaces are resolved in pages. I think this is some other issue than the original one. Here is more information on the original issue and the setup that did not work as expected:

  • next-translate 1.0.1
  • next.js 10.0.4 (configured to use Express as the backend server)

_app.tsx:

import withTranslation from "next-translate/withTranslation";

class MyApp extends App<Props> {
  static async getInitialProps({ Component, ctx }: any) {
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    return { pageProps };
  }

  render() {
    const { Component, pageProps, apollo, i18n } = this.props;
    const locale = i18n.lang === "fi" ? fiFI : enUS;

    return (
      <ApolloProvider client={apollo}>
        <ConfigProvider locale={locale}>
          <Component {...pageProps} />
        </ConfigProvider>
      </ApolloProvider>
    );
  }
}

export default withApollo(withTranslation(Ilmo));

Some other page component:

const TestPage: NextPage<Props> = (props) => {
  const [[id, token], setIdAndToken] = useState<[string, string]>([
    props.id || "",
    props.token || "",
  ]);
  // props.id and props.token are both undefined


  return (
    <div>test</div>
  );
};

TestPage.getInitialProps = async ({ query: { id, token } }) => ({
  id: typeof id === "string" ? id : null,
  token: typeof token === "string" ? token : null,
});

export default TestPage;

Express handling SSR:

import { parse } from "url";

import { Express } from "express";
import next from "next";

export default async function installSSR(app: Express) {
  const nextApp = next({
    dev: isDev,
    dir: `${__dirname}/../../../client/src`,
    quiet: !isDev,
    // Don't specify 'conf' key
  });

  const handlerPromise = (async () => {
    await nextApp.prepare();
    return nextApp.getRequestHandler();
  })();

  handlerPromise.catch((e) => {
    console.error("Error occurred starting Next.js; aborting process");
    console.error(e);
    process.exit(1);
  });

  app.get("*", async (req, res) => {
    const handler = await handlerPromise;
    const parsedUrl = parse(req.url, true);
    handler(req, res, {
      ...parsedUrl,
      query: {
        ...parsedUrl.query,
      },
    });
  });
}

With the above setup TestPage.getInitialProps is never executed. And since I don't need the actual i18n object in _app but just the locale, I was able to solve my issue with the code I outlined above.

Sorry I was not able to produce a reproducible example as I could figure out a way to run Next.js SSR on Codesandbox... Thanks for this library by the way, it's awesome!

rriski avatar Dec 30 '20 23:12 rriski

Thanks to report it @rriski

aralroca avatar Jan 03 '21 22:01 aralroca

Hi there! Looks like i have same issue with custom _app.js.

Versions:

    "typescript": "4.5.5"
    "react": "17.0.2",
    "next": "^12.0.10",
    "next-translate": "^1.4.0",

I made an example of this bug. https://github.com/VasiliyBP/next-translate

In pages/market.tsx getInitialProps doesn't run if i use nextTranslate in my next config. Do you know, maybe, any workaround except using loadNamespaces?

VasiliyBP avatar Apr 20 '22 12:04 VasiliyBP

Have you tried this?

const MarketPage = connect(mapStateToProps)(Market)
MarketPage.getInitialProps = getInitialProps
export default MarketPage;

Instead of:

Market.getInitialProps = getInitialProps
export default connect(mapStateToProps)(Market);

I don't know if the connect copies the getInitialProps correctly.

aralroca avatar Apr 20 '22 14:04 aralroca

Have you tried this?

Yes, even export default Market without connect doesn't work. I think it's because _app.tsx wrapped.

VasiliyBP avatar Apr 20 '22 15:04 VasiliyBP

I can make new issue if you want. @aralroca should i?

VasiliyBP avatar Apr 20 '22 15:04 VasiliyBP

the first comment on the issue was before 1.0 and we reimplemented everything to support the i18n routing of Next.js, but I see that in +1.0 it is not fixed at all so it is ok to stay in the same issue until it is solved.

aralroca avatar Apr 20 '22 15:04 aralroca

Wrapping is not a reason. Just custom _app.jsx break call getInitialProps in pages. Next code make it working, but this disables the ability to perform automatic static optimization, causing every page in your app to be server-side rendered.

MyApp.getInitialProps = async ({ Component, ctx }: any) => {
  let pageProps = {};

  if (Component.getInitialProps) {
    pageProps = await Component.getInitialProps(ctx);
  }

  return { pageProps };
};

VasiliyBP avatar Apr 21 '22 09:04 VasiliyBP

I believe this issue has been resolved with Next-translate 2.0, as we have rewritten the plugin and replaced the use of regex with a parser. This update has automatically addressed many of the issues related to attempting to parse items with regex.

I trust that this solution has fully resolved the matter, and as such, I will proceed to close the issue. Additionally, I would like to inform you that we have moved the plugin to this repository: https://github.com/aralroca/next-translate-plugin.

If, for any reason, you find that the issue has not been fully resolved, please feel free to reopen the issue on the next-translate-plugin repository.

Thank you very much.

aralroca avatar Feb 20 '23 17:02 aralroca