question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

i18n redirection through middleware causes multiple redirection during client side transitions

See original GitHub issue

Verify canary release

  • I verified that the issue exists in Next.js canary release

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 10 Home Single Language
Binaries:
  Node: 16.13.1
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant packages:
  next: 12.1.1
  react: 17.0.2
  react-dom: 17.0.2

What browser are you using? (if relevant)

Chrome

How are you deploying your application? (if relevant)

Other platform

Describe the Bug

For advanced i18n needs, I’m currently using middleware so that only some sets of pages have i18n enabled. e.g while accessing let’s say /pt/xyz redirects the user to /xyz since we don’t have the Portuguese content for that particular page.

The below piece of code works well when I directly enter the URL in the browser. But causes multiple redirections when I click a link on the page which causes a client-side transition to a different page

  if (!requested_page_is_i18n_enabled && locale !== 'en') {
      const url = nextUrl.clone();
      url.locale = 'en';
      return NextResponse.redirect(url);
    }

Expected Behavior

Looks like the return NextResponse.redirect(url); doesn’t work properly when we click on a Link component

whatever changes I apply to nextUrl, it seems like it doesn’t get applied but when I do a hard refresh, it works as expected

To Reproduce

/* eslint-disable no-console */
import { NextResponse } from 'next/server';
import supportedLanguages from '../public/locales/supportedLanguages';

const PUBLIC_FILE = /\.(.*)$/;

const pathsWhereLocalesAreEnabled = [
  '/jobs',
  '/jobs/[id]',
  '/remote-developer-jobs',
];

export function middleware(req) {
  try {
    const { nextUrl, headers } = req;
    const { locale } = nextUrl;

    if (PUBLIC_FILE.test(nextUrl.pathname)) {
      return undefined;
    }

    if (nextUrl.pathname.includes('/api')) {
      return undefined;
    }

    const browserDefaultLocale =
      headers.get('accept-language')?.split(',')?.[0] || 'en';

    if (locale === 'en' && browserDefaultLocale === 'en') {
      return undefined;
    }

    const websiteLocale = supportedLanguages.includes(browserDefaultLocale)
      ? browserDefaultLocale
      : 'en';

    const requested_page_is_i18n_enabled = pathsWhereLocalesAreEnabled.includes(
      req.page.name,
    );

    console.log(nextUrl.toString());

    if (!requested_page_is_i18n_enabled && locale !== 'en') {
      const url = nextUrl.clone();
      url.locale = 'en';
      return NextResponse.redirect(url);
    }

    if (requested_page_is_i18n_enabled) {
      const { locale } = nextUrl;
      const url = nextUrl.clone();

      if (locale === websiteLocale && locale === 'en') return undefined;

      if (locale === 'en') {
        url.locale = websiteLocale;
        return NextResponse.redirect(url);
      }

      return undefined;
    }

    // If everything else falls through continue on with response as normal
    return undefined;
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error(e);
  }
}

This is the code I am using, I don’t know how I can share how to reproduce this since I’m working on my company’s website. Pls help 😦

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:3
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
vinaynair39commented, Jun 21, 2022

Thanks a lot @javivelasco!

1reaction
vinaynair39commented, Apr 14, 2022

Good writeup from @vinaynair39

I also got this problem. It causes the browser to get locked up in an infinite loop, sending loads of requests to the same URL over and over, effectively crashing the page.

For anyone that just need this to work right now, here’s a solution I found:

export async function middleware(req: NextRequest) {
  // ...
  // ...
  if (shouldRedirect) {
    if (req.method == "HEAD") {
      // Fixes the problem with redirects by forcing a native page load
      return NextResponse.error();
    }
    // Your redirect
    return NextResponse.redirect(urlToRedirectTo);
  }
}

@erming that worked for me, thank you so much!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Advanced Features: Internationalized Routing - Next.js
When localeDetection is set to false Next.js will no longer automatically redirect based on the user's preferred locale and will only provide locale...
Read more >
Next.js Redirect from / to another page - Stack Overflow
Just redirect as you would do in any React app. Prefer client-side redirections first. Just using useEffect + router.push , and that's it....
Read more >
Redirecting - Routing - Ember Guides
Calling transitionTo() on the router service will stop any transitions currently in progress and start a new one, functioning as a redirect.
Read more >
Next.js 12.2 Overview: Middleware, Layouts, and more
Next.js 12.2 introduces stable Middleware and On-Demand ISR, experimental Edge SSR and API Routes, and more.0:00 Intro1:50 Agenda2:30 ...
Read more >
Settings - Django documentation
Note that the redirect may cause any data submitted in a POST request to be lost. The APPEND_SLASH setting is only used if...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found