next.js: 307 redirect loop when using locale together with middleware in 13.5.1

Link to the code that reproduces this issue

https://github.com/c0per/307-loop-i18n-middleware

To Reproduce

  1. set defaultLocale to something different than preferredLocale (from header accept-language)
  2. npm run dev
  3. access http://localhost:3000/en or http://localhost:3000/fr or http://localhost:3000 or with trailing slash

Current vs. Expected behavior

image

Currently, Next.js 13.5.1 will stuck in 307 loop if:

  • turn on localeDetection (which is enabled by default)
  • set defaultLocale different from user’s preferredLocale
  • use a middleware

Expected behavior:

It doesn’t stuck.

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: 18.16.0
      npm: 9.5.1
      Yarn: 1.22.19
      pnpm: N/A
    Relevant Packages:
      next: 13.5.1
      eslint-config-next: 13.5.1
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.2.2
    Next.js Config:
      output: N/A

Which area(s) are affected? (Select all that apply)

Internationalization (i18n)

Additional context

No response

NEXT-2627

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Reactions: 53
  • Comments: 52 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Just ran into this as well. No fix yet, not even an acknowledgement.

Having to deal with these kinds of issues with every patch- or minor-level Next.js upgrade is getting so frustrating and really makes me wonder if Next.js is still on the right trajectory. Putting that much energy into stuff like RSCs and leaving existing users in the dust with stuff like this will eventually come back to bite you, Vercel. Make the foundations work (middleware AND i18n in the same app is not that unusual, isn’t it?), then move on to the fancy stuff.

Hi, the above fix is now available in v14.1.3, please update and give it a try!

@leerob This broke our production environment. This ticket has a reproduction in it. What more needs to happen to get responses from Vercel?

This just goes to show that people are losing faith in Vercel and Next.js, IMHO. If we can’t use the features a framework provides out of fear they might break at any time, why use a (more fully featured) framework at all? Oh, sorry, I forgot: Streaming components, form fields submitting directly to functions… Who needs working I18n and middlewares if you can have the future™️? 😄

here’s something that has worked for us, maybe it will help someone too - In the i18n config, disable the nextJs locale detection, like:

{
  locales: ['en', 'de', 'ja'],
  defaultLocale: 'en',
  defaultNS: 'common',
  localeDetection: false,
 }

we handle the redirecting manually in our middleware and for the locale string we use the next-translate@2.6.2

@diegopalat It should be in 14.1.3.

@petrovmiroslav this change was not backported to 14.1.2, we updated the release notes to mention we only added critical fixes and not all changes from canary

Would love to see an update on this so we can upgrade to v14 for now we are pinned to v13.

@ijjk @timneutkens @huozhi do you guys have any ideas or thoughts about this?

Hey @valleywood!

You’re not alone; I’m also banging my head against the wall trying to get middlewares to play nicely with Next.js i18n… 😅

My problem is that the middleware function isn’t called at all for the root URL (all other URLs not being on the root, like /en/whateverpage/ works)

I actually faced the exact same issue and was able to fix it simply by adding "/" to the array of matchers so my config looks like this:

export const config = {
  matcher: [
    "/", // Required when i18n is enabled, otherwise middleware won't be executed on index route
    "/((?!api/|_next/|_static/|_vercel|fonts|images/|[\\w-]+\\.\\w+).*)",
  ],
};

Hope that this will unblock you! 😉

Aiming to get a minimal reproducible example ready and open an issue in the coming days…

The bug first appears in version 13.4.20-canary.24, 13.4.20-canary.23 is fine.

@samcx now I’ve added it, sorry. https://github.com/borjalo/middleware-307-repro

I want to add a rewrite to modify the URL.

Hi, the above fix is now available in v14.1.3, please update and give it a try!

I’ve tested on my side and I had to delete the build cache for the issue to dissapear. After that, so far, I’m not able to reproduce the redirect loop even with different combinations of the browser locale and defaultLocale settings.

It would be great to hear from others before sending this to production. 🚀

The issue still reproduces in v14.1.2. Redirect loop appears after adding any middleware.ts, even if it looks like

import {NextResponse} from "next/server";

export const middleware = () => {
  return NextResponse.next();
};

hi, i tried to fix this in #62435. kindly check it out

Hey @samcx. Sorry for pinging but would you be able to take a look?

@raphaelsaunier Thank you so much! 😍 Your code together with localeDetection: false actually solved my issue both with the middleware being called and not forcing me to use trailingSlash: false.

Was trying something similar like this before but wasn’t able to get my regExp right I guess.

Sounds great if you are able to provide a reproduction repo because is would be good to have both middleware and localeDetection working simultaneously, now it seems one have to choose. 🙏

Have a wonderful weekend!

Hello, is it possible to provide us a complete example for disabling localeDetection without i18n, please?

Thanks in advance!

Best Loïc

Same here. Have infinite redirect problem using next 14

@raphaelsaunier Thank you so much! 😍 Your code together with localeDetection: false actually solved my issue both with the middleware being called and not forcing me to use trailingSlash: false.

Was trying something similar like this before but wasn’t able to get my regExp right I guess.

Sounds great if you are able to provide a reproduction repo because is would be good to have both middleware and localeDetection working simultaneously, now it seems one have to choose. 🙏

Have a wonderful weekend!

I ended up removing all NextJS specific locales, which means I had to create a language slug for each language and do some other manual things. In the end it works better and is more bullet proof against breaking changes. This is also the way forward in the App router AFAIK.

Does the Next team even acknowledge this issue?

Seems to only affect the index route for me.

Client-side routing is also broken with localization when middleware file is present. The locale always becomes the default locale when clicking on a <Link /> that routes to something such as https://page.com/de - it returns 404. If I do a refresh on that route (server-side routing) then it works.