You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Next.js自定义重定向中间件优先于next-intl生效?

如何让自定义语言重定向优先于next-intl的路由中间件生效?

你遇到的问题是自定义重定向中间件被next-intl的路由逻辑覆盖,核心原因是链式中间件没有在返回重定向后终止后续流程,导致next-intl仍会处理请求并触发它自己的重定向。以下是两种可行的解决方法:

方法一:手动控制中间件执行流程(替代链式调用)

放弃使用@nimpl/middleware-chain,手动按顺序执行中间件,确保自定义重定向生效后直接返回响应,跳过后续逻辑:

修改middleware.ts:

import { NextRequest } from 'next/server';
import { pagesWhiteListMiddleware } from './middlewares/pagesWhiteList';
import handleI18nRouting from './middlewares/handleI18nRouting';
import handleLocaleRedirect from './middlewares/handleLocaleRedirect';

export default async function middleware(request: NextRequest) {
  // 先执行自定义重定向逻辑
  const redirectResp = await handleLocaleRedirect(request);
  if (redirectResp) {
    // 如果返回了重定向响应,直接返回,不执行后续中间件
    return redirectResp;
  }

  // 执行next-intl路由中间件
  const i18nResp = await handleI18nRouting(request);
  
  // 执行白名单中间件(根据实际需求调整传递参数)
  const finalResp = await pagesWhiteListMiddleware(request, i18nResp);
  return finalResp || i18nResp;
}

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|next-assets|favicon.ico|sw.js|site.webmanifest).*)',
  ],
};

同时修改handleLocaleRedirect.ts,确保只有需要重定向时才返回响应,否则返回undefined:

import { NextRequest, NextResponse } from 'next/server';

export default async function handler(request: NextRequest) {
  // 从Cookie获取目标语言(替换成你的Cookie键名)
  const targetLocale = request.cookies.get('your-locale-cookie')?.value;
  // 从当前URL解析出当前语言(实现你自己的解析逻辑)
  const currentLocale = request.nextUrl.pathname.split('/')[1];
  // 定义支持的语言列表
  const supportedLocales = ['en', 'zh'];

  if (targetLocale && supportedLocales.includes(targetLocale) && targetLocale !== currentLocale) {
    // 构造新的URL,保留查询参数
    const newPathname = `/${targetLocale}${request.nextUrl.pathname.replace(/^\/[a-z]{2}/, '')}`;
    const newUrl = new URL(newPathname, request.nextUrl.origin);
    newUrl.search = request.nextUrl.search;
    
    return NextResponse.redirect(newUrl);
  }

  // 不需要重定向时返回undefined,让后续中间件处理
  return undefined;
}

方法二:扩展next-intl的语言检测逻辑(更优雅)

直接利用next-intl自身的detectLocale配置,优先读取项目原有Cookie,不需要额外写重定向中间件:

修改i18n/routing.ts:

import { defineRouting } from 'next-intl/routing';

export const routing = defineRouting({
  locales: ['en', 'zh'], // 替换成你的支持语言列表
  defaultLocale: 'en',
  // 自定义语言检测逻辑,优先从Cookie读取
  async detectLocale(request) {
    // 从Cookie获取语言
    const cookieLocale = request.cookies.get('your-locale-cookie')?.value;
    if (cookieLocale && ['en', 'zh'].includes(cookieLocale)) {
      return cookieLocale;
    }
    
    // fallback到默认的Accept-Language头检测
    const acceptLang = request.headers.get('accept-language');
    if (acceptLang) {
      const primaryLang = acceptLang.split(',')[0].split('-')[0];
      if (['en', 'zh'].includes(primaryLang)) {
        return primaryLang;
      }
    }

    // 最终fallback到默认语言
    return 'en';
  }
});

然后修改handleI18nRouting.ts,去掉多余的逻辑(如果不需要处理link头可以简化):

import { routing } from '../i18n/routing';
import createMiddleware from 'next-intl/middleware';

export default createMiddleware(routing);

这种方法让next-intl直接使用你的Cookie语言,避免了自定义重定向和next-intl逻辑冲突的问题,是更符合next-intl设计的方案。

内容的提问来源于stack exchange,提问作者Alex Buznik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:04:54