amannn / next-intl

🌐 Internationalization (i18n) for Next.js
https://next-intl-docs.vercel.app
MIT License
2.58k stars 236 forks source link

Cannot use Server Actions + Monorepo setup - TypeError: Cannot read properties of undefined (reading 'getRequestConfig') #1229

Closed dBianchii closed 2 months ago

dBianchii commented 3 months ago

IMPORTANT EDIT: I changed the title of this issue, as I have found out that the problem was not related to trpc. Just related to using Server Actions + Monorepo setup. I edited the issue description to best describe the problem as my latest advancement on this

Description

I have a file exporting a server action:

"use server";

// I am trying to import getTranslations from my internal package, which exports getTranslations:
import { getTranslations } from "@kdx/locales/next-intl/server"; //! THIS ONE DOESN'T WORK

//The above import breaks completely, but if I use this commented line instead:
// import { getTranslations } from "next-intl/server";//! This one works!! You can uncomment this line and comment the one above to see the difference

export const finishKodixCareOnboardingAction = async () => {
  const t = await getTranslations();
  console.log(t("Title"));
};

Whenver I import and call getTranslations() from my internal package, I get the error:

TypeError: Cannot read properties of undefined (reading 'getRequestConfig')
    at Object.getRequestConfig (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/app/[locale]/apps/kodixCare/onboarding/page.js:10:50885)
    at 597 (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/app/[locale]/apps/kodixCare/onboarding/page.js:8:83597)
    at t (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/webpack-runtime.js:1:127)
    at 8651 (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/app/[locale]/apps/kodixCare/onboarding/page.js:8:155134)
    at t (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/webpack-runtime.js:1:127)
    at 4078 (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/app/[locale]/apps/kodixCare/onboarding/page.js:8:156120)
    at t (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/webpack-runtime.js:1:127)
    at 7230 (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/app/[locale]/apps/kodixCare/onboarding/page.js:8:154061)
    at t (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/webpack-runtime.js:1:127)
    at 6147 (/home/gabriel/Documents/Github/kodix-turbo/apps/kdx/.next/server/app/[locale]/apps/kodixCare/onboarding/page.js:10:50948) {
  digest: '4022314656'

NOTE: This issue is happening in production only (next start), and not in development (next dev)!

Verifications

Mandatory reproduction URL

https://github.com/dBianchii/next-intl-error-minimalreproduction

Reproduction description

I have tried to strip down as much as possible from my actual codebase and just show the current error.

Steps to reproduce:

  1. Open reproduction link,
  2. Clone repo
  3. Make sure you have pnpm@9.6.0 installed, or install it with npm i -g pnpm@9.6.0
  4. Run pnpm i
  5. Run pnpm build
  6. Go to apps/kdx with cd apps/kdx
  7. Run pnpm start
  8. Cause the error by clicking the button on the screen at localhost:3000
  9. Now, please go to the file apps/kdx/src/app/[locale]/actions/onboardingActions.ts
  10. Comment the first import, uncomment the second import
  11. Build the next server again and rerun next start
  12. Now the error is gone
  13. Cry

Expected behaviour

It should not error when I call await getTranslations() from an exported package of my monorepo inside a server action

dBianchii commented 3 months ago

TLDR: Importing and using getTranslations from my monorepo package @kdx/locales/next-intl/server inside a server action doesn't work, while importing directly from node_modules does. :crying_cat_face:

amannn commented 3 months ago

Why do you intend to wrap/re-export getTranslations in the first place? It's intended to be used directly in apps, I don't really see the need why you have to export it from another package.

Can you provide some background?

dBianchii commented 3 months ago

Why do you intend to wrap/re-export getTranslations in the first place? It's intended to be used directly in apps, I don't really see the need why you have to export it from another package.

Can you provide some background?

I am doing it like that because I have multiple packages that need to use the getTranslations and other apis from next-intl. I have for example @kdx/api, @kdx/auth, and @kdx/validators. All of these packages are used by my next-js main app: @kdx/kdx. I could in theory install next-intl on all of these packages, but I would much rather have a single source of truth for where my next-intl resources are. With this @kdx/locales package, I can also serve use-intl resources for my react-native applications, and thus centralize all of my messages inside this package. It's the best way to do it in a monorepo setup, and I think this should be supported

I believe that this error is sometimes occuring because getRequestConfig is not able to be found. The strange thing is that this behavior is quite inconsistent and sometimes does work....

amannn commented 3 months ago

Thanks for providing details! Where do you draw the line here? I mean, you also wouldn't map libraries like React, Next.js or lodash if they are used in multiple packages, right? I'd really suggest to import functionality from next-intl directly from the library. This also ensures that other tools like the VSCode integration work correctly. Future improvements like #1 might rely on an import from next-intl, so sticking to that ensures you're on the best path going forward.

Regarding React Native, you can absolutely import from use-intl there, as well as in shared modules with your Next.js app.

As for the issue you've reported, I unfortunately don't know where this originates from—sorry! As it only occurs in production and apparently only sometimes, this might sound rather hairy to debug.

dBianchii commented 2 months ago

@amannn , thanks for the detailed response.

About drawing the line for exports from a separate package, I guess it just made sense for me specifically for this package because I wanted to keep my messages (json files) in a separate and shared place for my monorepo. Since the messages are in a separate @kdx/locales package, it made sense for me to also re-export next-intl there, because after all, this package would be the main way to translate stuff in my repo everywhere.

In any case, I still think I can only keep the messages there, and install next-intl everywhere I need it. Is this what you recommend me doing then?

Thanks!

dBianchii commented 2 months ago

Just to share how I am doing right now, most places in my next-js app I am importing the helpers from my internal package, and it's working 99% of the time.

image

If you confirm it's best for me to remove next-intl re-exports from that package, I'll adjust it to install directly everywhere I need it. Thanks!

amannn commented 2 months ago

In any case, I still think I can only keep the messages there, and install next-intl everywhere I need it. Is this what you recommend me doing then?

Sure, sounds fine to me if this makes sense for your codebase!

If you confirm it's best for me to remove next-intl re-exports from that package, I'll adjust it to install directly everywhere I need it. Thanks!

Yep, that would be my recommendation! 🙂

I'm going to close this issue as it seems to have been resolved, hope this matches your understanding!