vercel / next.js

The React Framework
https://nextjs.org
MIT License
123.35k stars 26.32k forks source link

I18n configuration in next.config.js breaks app directory #53724

Open fabio-nettis opened 11 months ago

fabio-nettis commented 11 months ago

Verify canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 22.6.0: Wed Jul  5 22:21:56 PDT 2023; root:xnu-8796.141.3~6/RELEASE_X86_64
    Binaries:
      Node: 20.5.0
      npm: 9.8.0
      Yarn: 3.5.0
      pnpm: 8.6.12
    Relevant Packages:
      next: 13.4.14-canary.0
      eslint-config-next: 13.4.13
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

App Router, Internationalization (i18n), Routing (next/router, next/navigation, next/link)

Link to the code that reproduces this issue or a replay of the bug

https://github.com/fabio-nettis/next-i18n-error

To Reproduce

This issue is directly related to my previous issue #53665 You can find more about the discovery process of this bug in this discussion.

  1. Clone the repository
  2. Try to navigate to any of the defined pages
  3. You will encounter a not found error for each of the defined routes.

Once you have seen the error you can then do the following steps to revert the broken app folder:

  1. Remove i18n key from next config
  2. Try to navigate to any of the defined pages
  3. See the defined page

Describe the Bug

Since version 13.4.13-canary.0 an application previously working fine on version 13.4.12 returns a 404 status code for every page in the app folder when the i18n setting is set in the next config file.

Expected Behavior

Setting the i18n in the next config file should not break the whole application' routing.

Which browser are you using? (if relevant)

Chrome 114.0.5735.106 (Official Build) (x86_64)

How are you deploying your application? (if relevant)

next dev

NEXT-1512

fabio-nettis commented 11 months ago

For anybody that needs a solution now, here is a repository with a working and scalable i18n implementation that does not use the i18n settings inside next.config.js.

vesurbag commented 11 months ago

For anybody that needs a solution now, here is a repository with a working and scalable i18n implementation that does not use the i18n settings inside next.config.js.

Thanks, but it doesn't work in case of default locale shouldn't show in the url, e.g.: en (default) -> /blog/post de -> /de/blog/post

fabio-nettis commented 11 months ago

@vesurbag I will be tracking this issue here, currently optional route parameters are not supported, they only work for catch-all segments.

igorovic commented 10 months ago

same issue. tested with next@13.4.20-canary.13

dmgawel commented 10 months ago

The issue persists in v13.5.2.

As we have a lot of translated pages in Pages Router, this bug stops us from upgrading Next and adopting the App Router incrementally.

The moment I remove i18n config, the App Router works again, but then everything in Pages Router stops working.

boredland commented 10 months ago

The moment I remove i18n config, the App Router works again, but then everything in Pages Router stops working.

And does the app dir pages work in production? For me they only work in development.

dmgawel commented 10 months ago

And does the app dir pages work in production? For me they only work in development.

For us, they do, but we're stuck on v13.2.

fabio-nettis commented 10 months ago

same issue. tested with next@13.4.20-canary.13

Check out the example repository I have provided, it eliminates the need for the i18n key inside next.config.js. We currently use it in production and it works just fine.

dmgawel commented 10 months ago

Check out the example repository I have provided, it eliminates the need for the i18n key inside next.config.js. We currently use it in production and it works just fine.

@fabio-nettis Appreciate trying to find a workaround. However, i18n config key is not needed for internationalization in App Router, it's meant to be used in the Pages Router. In fact, your example repository implements a standard approach suggested by Next.js docs: https://nextjs.org/docs/app/building-your-application/routing/internationalization

It's not a problem, of course ;-) However, that's not a workaround for this issue.


To sum up: Existence of i18n config key needed for internationalization in Pages Router breaks App Router, and there is currently no workaround that would enable one to use internationalization in Pages Router and App Router (in general) at the same time.

fabio-nettis commented 10 months ago

Check out the example repository I have provided, it eliminates the need for the i18n key inside next.config.js. We currently use it in production and it works just fine.

@fabio-nettis Appreciate trying to find a workaround. However, i18n config key is not needed for internationalization in App Router, it's meant to be used in the Pages Router. In fact, your example repository implements a standard approach suggested by Next.js docs: https://nextjs.org/docs/app/building-your-application/routing/internationalization

It's not a problem, of course ;-) However, that's not a workaround for this issue.

To sum up: Existence of i18n config key needed for internationalization in Pages Router breaks App Router, and there is currently no workaround that would enable one to use internationalization in Pages Router and App Router (in general) at the same time.

@dmgawel Thanks for the response! it would probably be wise to explicitly mention the required absence of the i18n key in next.config.js for the app router, since this did not resonate to me personally, and based on the issue activity, suggestively neither did to other people.

Furthermore I'd politely recommend to extend the current documentation on localization inside the app router to be a bit closer to a real-world approach as seen in the repository I provided.

mataspetrikas commented 9 months ago

so to summarize the issue - the incremental migration to the app router is not possible for localized NextJs apps, right?

dmgawel commented 9 months ago

so to summarize the issue - the incremental migration to the app router is not possible for localized NextJs apps, right?

Right 👍

mataspetrikas commented 9 months ago

it looks that the locale is not being updated in getServerSideProps/getStaticProps from the next version 13.4.13, at least what this issue seems to suggest:

andre-lergier commented 9 months ago

@dmgawel so to summarize the issue - the incremental migration to the app router is not possible for localized NextJs apps, right?

We are on next 13.5.4 and I can confirm this conclusion. Does anyone know a version of next where it was still working to use App and Pages router simultaneously with i18n?

noreiller commented 9 months ago

@dmgawel so to summarize the issue - the incremental migration to the app router is not possible for localized NextJs apps, right?

We are on next 13.5.4 and I can confirm this conclusion. Does anyone know a version of next where it was still working to use App and Pages router simultaneously with i18n?

On my side, I'm re-implementing the i18n feature with a middleware. The only downside is that I cannot remove nor disable the locale property on the next/router and next/link modules. Otherwise, even if I have to update all the links to include the locale in the href, it's not so complicated. This way, the locale (from the route segment [locale]) is retrieved from the query params and it works like in App Router.

guillaumeLamanda commented 9 months ago

It seems to be resolved on the latest release. However, the ##46622 still persist

dmgawel commented 9 months ago

It seems to be resolved on the latest release

Tested on v13.5.6, unfortunately it still doesn't work.

Abd2rahman commented 8 months ago

It still doesn't work on v14. Has anyone found a workaround to resolve this issue?

fabio-nettis commented 8 months ago

For anybody that needs a solution now, here is a repository with a working and scalable i18n implementation that does not use the i18n settings inside next.config.js.

@Abd2rahman Check the linked repository. The only thing this example does not support are optional locale paths.

Abd2rahman commented 8 months ago

Thank you @fabio-nettis, but the solution you are suggesting uses only the app router, and the bug occurs only when we combine both the app router and page router in the same project. Does it work as well with page router ?

dmgawel commented 8 months ago

I created a repository that recreates the issue with a minimal amount of code. It features both Pages and App router example, to highlight the issue when both are used:

https://github.com/dmgawel/next-i18n-issue

shinwonse commented 8 months ago

I created a repository that recreates the issue with a minimal amount of code. It features both Pages and App router example, to highlight the issue when both are used:

https://github.com/dmgawel/next-i18n-issue

It is same situation with mine🥲 Have you ever tried use middleware as Next.js docs said?

shinwonse commented 8 months ago

I think I almost find solution from https://github.com/amannn/next-intl/tree/main/examples/example-app-router-migration.

Gregorein commented 7 months ago

bump on the thread - what's the status of this issue? I followed the next docs for the middleware code and I'm hitting the exact same issue somewhere between sending a response and next trying to unravel the [lang] path param

Gregorein commented 7 months ago

@shinwonse "almost?"

shinwonse commented 7 months ago

@shinwonse "almost?"

I thought I almost solved it with next-intl package, but it was failed and I am still struggling with it 😂

Gregorein commented 7 months ago

I got it working using their official doc https://next-intl-docs.vercel.app/docs/getting-started/app-router. I've checked your repo, @shinwonse and it looks like you're almost there, you'd have to use the lang/locale param in the layout instead of using a hook and call the unstable_setRequestLocale() with that locale.

Multiply commented 5 months ago

We're using a middleware to match domain names and paths, and then we either prepend to, or change the prefix of the path to the fully qualified locale.

This works well for the pages router, but as long as i18n is configured, it won't match app/[locale]/example/page.tsx, only app/example/page.tsx when visiting /example.

The middleware does indeed rewrite to /en-GB/example, but the app router seems to remove that part or just ignore the rewrite, when i18n is configured.

Edit: In order to not be blocked by this issue, we ended up abandoning the use of i18n in next.config, and instead opted to handle it using NextResponse.rewrite in our middleware, and moving all pages routes to pages/[locale]. After moving all pages, we had to replace all uses of useRouter's locale, and AppContext's locale param.

berkaytheunicorn commented 4 months ago

This issue should be on docs, I just randomly spent 3 hours to remove the i18n config. 🫠

Alenriquez96 commented 4 months ago

Any info on how to solve this problem with output:export? It works fine in local but not when I generate the static files.

dmgawel commented 4 months ago

We've successfully worked around this bug by using next-intl routing middleware:

  1. Disable native Next.js i18n functionalities (remove i18n key from next.config.js).
  2. Follow next-intl docs on adding routing middleware to your project: https://next-intl-docs.vercel.app/docs/routing/middleware. This also means you need to nest your pages under a dynamic segment (for example [lang]).
  3. You need to update your code in all places that rely on context.locale, and read the locale from page params instead.

next-intl provides a reference repo for using i18n in Pages and App, without Next.js i18n: https://github.com/amannn/next-intl/tree/main/examples/example-app-router-migration

Keep in mind, that you're not forced to use translation capabilities from next-intl. You can continue using whatever you've used before.

adil-hublo commented 4 months ago

@dmgawel the way next-intl imports JSON locales in the i18n.ts file does not accept anything more than locale as a parameter; which prevent use of namespaces to only fetch the files we want, like in next-i18next though I try to mess with it; thanks for all the information!

dmgawel commented 3 months ago

the way next-intl imports JSON locales in the i18n.ts file does not accept anything more than locale

@adil-hublo You don't have to use translation function from next-intl, you're free to continue using next-i18next if that's what you've been using. Just read the locale from the query now. If your pages are nested under pages/[lang]/, then it's:

- await serverSideTranslations(context.locale, requiredNamespaces)
+ await serverSideTranslations(context.query.lang, requiredNamespaces)
adil-hublo commented 3 months ago

@dmgawel sure, this is exactly what I did for the pages router, but for the migrated pages to App Router, I am supposed to use next-intl right? And this is where I lack of this "filter" to get only the namespaces I need, instead of all my translation files

VMLuca commented 3 months ago

Anything new on this topic? It's a pity that you read everywhere that you can run the app router and the page router in parallel and then it doesn't work because of the internationalisation (really without a workaround).

rachellcarroll commented 2 months ago

@dmgawel I tried out next-intl as well, following their app router docs and referencing next-intl's sample app router migration repo. It seems to be working, but I'm getting errors at the console. Error handling upgrade request TypeError: Cannot read properties of undefined (reading 'bind') at DevServer.handleRequestImpl (/Users/<repo_name>/node_modules/next/dist/server/base-server.js:478:50)

"next": "14.2", "next-intl": "3.11.3", Did you see this too?

rachellcarroll commented 2 months ago

@dmgawel I just downgraded to next@13.4.12 and those errors went away!

rnnyrk commented 2 months ago

Running into the same issue running app router and pages router in parallel with a migration. Thought about removing the i18n config to make the app router working and set the locale on the req.nextUrl.clone manually before a rewrite. Unfortunately running into this issue using this:

Screenshot 2024-05-13 at 13 36 17

We're not using next-intl but i18next and react-i18next following this guide: https://locize.com/blog/next-app-dir-i18n/. In my opinion the NextJS team really should have thought this through or otherwise marked the migrating as impossible for internationalised apps.

Think this is the only solution which I will try now: https://github.com/vercel/next.js/issues/53724#issuecomment-1947800905

vordgi commented 2 weeks ago

For those who wanna keep the principle of i18n and static generation but don't want to use [the excellent for their tasks] next-intl, I have created the package @nimpl/router, which transfers the logic of rewrites, redirects, i18n, and basePath from next.config.js to middleware (but with the difference that it works).

Example of a localized application on App Router - https://github.com/vordgi/nimpl-router/blob/main/examples/base/src/middleware.ts;

Documentation - https://nimpl.tech/router