-
Notifications
You must be signed in to change notification settings - Fork 30.1k
Description
Link to the code that reproduces this issue
https://github.com/stkimmoyo/next-16-redirect-issue
To Reproduce
- Clone the repository and install dependencies
- Run npm run build then npm run start
- Navigate to http://localhost:3000/my-start
- Click the "Go to Internal Redirect Page" link
- Observe the page fails to render (blank page or error)
Note: The issue does NOT occur in development mode (npm run dev).
Note: Direct URL access works correctly, only client-side navigation via Link fails.
src/proxy.ts (Middleware/Proxy):
export function proxy(request: NextRequest) {
const url = new URL(request.url);
if (!url.searchParams.has("proxy-params")) {
url.searchParams.set("proxy-params", "my-proxy");
return NextResponse.redirect(url.toString());
}
return NextResponse.next();
}src/app/my-startpage.tsx (Server Component):
import Link from "next/link";
export default function MyStartPage() {
return (
<div>
<Link href="/my-internal-redirect">
Go to Internal Redirect Page →
</Link>
</div>
);
}src/app/my-internal-redirect/page.tsx (Server Component):
export default async function MyInternalRedirectPage({ searchParams }: Props) {
const params = await searchParams;
if (!params["internal-params"]) {
currentParams.set("internal-params", "my-params");
redirect(`/my-internal-redirect?${currentParams.toString()}`);
}
return <div>...</div>;
}Current vs. Expected behavior
Current behavior:
When clicking a Link to navigate from /my-start to /my-internal-redirect in production build, the page fails to render. The client-side navigation appears to break when handling multiple redirects (one from Middleware/Proxy and one from Server Component's redirect()).
Expected behavior:
The page should render correctly after both redirects complete:
- Middleware/Proxy adds
proxy-params=my-proxy - Server Component adds
internal-params=my-params - Final URL:
/my-internal-redirect?proxy-params=my-proxy&internal-params=my-params - Page renders successfully showing the params
Provide environment information
Operating System:
MacOs 26.1
Binaries:
Node: 22.17.1
npm: 10.9.2
Relevant Packages:
next: 16.0.10
react: 19.2.1
react-dom: 19.2.1
Next.js Config:
output: N/A & standaloneWhich area(s) are affected? (Select all that apply)
Linking and Navigating, Redirects, Middleware
Which stage(s) are affected? (Select all that apply)
next build (local), next start (local)
Additional context
Summary
Client-side navigation (via <Link>) fails when:
- Middleware/Proxy performs a redirect to add query params
- Server Component also performs a redirect() to add different query params
Browser Console Error:
Throttling navigation to prevent the browser from hanging. See . Command line switch --disable-ipc-flooding-protection can be used to bypass the protection
Key observations:
- ✅ Works in npm run dev (development mode)
- ✅ Works with direct URL access (full page load)
- ✅ Works with client-side hard navigation via Link in production build
- ❌ Fails only with client-side navigation via Link(include prefetch) in production build
Workaround:
Using prefetch={false} on the Link component works around the issue:
Real-world Use Case & Migration Context
Business Requirements:
- Middleware/Proxy: Needs to maintain common search params across all pages
- (e.g., tracking params, session identifiers, feature flags)
- Specific Pages: Some pages need to initialize their own search params on first visit
- (e.g., default filters, page-specific state)
This is a common pattern where:
- Middleware/Proxy handles global/shared query params
- Individual pages handle page-specific query params
Migration Context:
- This issue was discovered during migration from Next.js 14 to Next.js 16
- The same code pattern worked correctly in Next.js 14
- After upgrading to Next.js 16, multiple redirects causes infinite loop