Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Middleware] Locale in NextResponse.rewrite(...) path ignored for dynamic routes when basepath is set and skipMiddlewareUrlNormalize is true #65746

Open
joslarson opened this issue May 14, 2024 · 0 comments
Labels
bug Issue was opened via the bug report template. Middleware Related to Next.js Middleware Pages Router Related to Pages Router.

Comments

@joslarson
Copy link

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/localized-slugs-y6fgq8

To Reproduce

Set the following in next.config.js to add basepath, enable path based localization, and to set skipMiddlewareUrlNormalize to true.

const nextConfig = {
  basePath: "/basepath",
  i18n: {
    defaultLocale: "en-US",
    locales: ["en-US", "es", "fr"],
  },
  skipMiddlewareUrlNormalize: true,
};

module.exports = nextConfig;

Next create middleware with a rewrite to a different locale (I've setup the middleware here to read a query param to override the locale):

const { NextResponse } = require("next/server");

const SKIP = /^\/(basepath\/)?(_next).*/;

export function middleware(request) {
  if (SKIP.test(request.nextUrl.pathname)) return NextResponse.next();

  const locale = request.nextUrl.searchParams.get("lang");
  if (!locale) return NextResponse.next();

  const url = request.nextUrl.clone();
  if (!url.pathname.startsWith(`/${locale.toLowerCase()}`)) {
    url.pathname = `/${locale.toLowerCase()}${url.pathname}`;
  }

  console.log("rewrite to:", url.href);

  return NextResponse.rewrite(url);
}

Next create a dynamic page such as pages/test/[slug].tsx, and print out the locale:

import Link from "next/link";
import { useRouter } from "next/router";

const Page = () => {
  const router = useRouter();
  return (
    <>
      {router.pathname}: {router.locale}
    </>
  );
};

export default Page;

Go to that page with the lang param set to a different locale: /basepath/test/dynamic?lang=fr, you'll see that the redirect url logs correctly as /basepath/fr/test/dynamic, but the page loads with the router reporting en-US as the local.

Try these same steps for a non dynamic route, and you'll see that it does work in that case.

Pinning to ~13.3.0 fixes the issue, but no newer version resolves the issue.

Current vs. Expected behavior

I expect dynamic routes to respect rewrites the same as non-dynamic routes, where currently in the above scenario, that is not the case.

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
  Available memory (MB): 8198
  Available CPU cores: 4
Binaries:
  Node: 20.11.1
  npm: 10.2.4
  Yarn: 1.22.19
  pnpm: 8.15.4
Relevant Packages:
  next: 14.2.3 // Latest available version is detected (14.2.3).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

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

Middleware, Pages Router

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

next dev (local), next build (local), next start (local)

Additional context

No response

@joslarson joslarson added the bug Issue was opened via the bug report template. label May 14, 2024
@github-actions github-actions bot added Middleware Related to Next.js Middleware Pages Router Related to Pages Router. labels May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. Middleware Related to Next.js Middleware Pages Router Related to Pages Router.
Projects
None yet
Development

No branches or pull requests

1 participant