next.js: I18n configuration in next.config.js breaks app directory

Verify canary release

  • I verified that the issue exists in the latest Next.js 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

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 24
  • Comments: 37 (2 by maintainers)

Commits related to this issue

Most upvoted comments

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.

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

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.

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.

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).

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

It seems to be resolved on the latest release

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

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

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.

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.

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

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.

@shinwonse “almost?”

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

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

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.