Next.js I18n重定向问题:如何实现全页面自动重定向?
问题解决:让Next.js所有页面根据NEXT_LOCALE Cookie自动重定向
要实现所有页面都能根据NEXT_LOCALE Cookie自动重定向到对应语言路径,需要利用Next.js的**中间件(Middleware)**全局拦截路由请求——原组件内的逻辑仅在组件加载时生效,无法处理直接访问子页面的场景(比如刷新/about或直接输入该URL)。
步骤1:创建中间件文件
在项目根目录下创建middleware.js(或middleware.ts),处理所有路由的重定向逻辑:
import { NextResponse } from 'next/server'; import { match } from '@formatjs/intl-localematcher'; import Negotiator from 'negotiator'; // 与next.config.js中配置的locales保持一致 const locales = ['en', 'pl', 'fr']; const defaultLocale = 'en'; // 获取目标语言:Cookie优先级 > 请求头偏好语言 > 默认语言 function getLocale(request) { // 优先读取Cookie中的语言设置 const cookieLocale = request.cookies.get('NEXT_LOCALE')?.value; if (cookieLocale && locales.includes(cookieLocale)) { return cookieLocale; } // 无Cookie时,解析请求头的用户偏好语言 const headers = { 'accept-language': request.headers.get('accept-language') || '' }; const languages = new Negotiator({ headers }).languages(); return match(languages, locales, defaultLocale); } export function middleware(request) { const pathname = request.nextUrl.pathname; // 判断当前路径是否已包含语言前缀(如/fr/about) const pathHasNoLocale = locales.every( locale => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}` ); // 路径无语言前缀时,重定向到带目标语言前缀的路径 if (pathHasNoLocale) { const targetLocale = getLocale(request); return NextResponse.redirect( new URL(`/${targetLocale}${pathname.startsWith('/') ? '' : '/'}${pathname}`, request.url) ); } } // 指定中间件作用范围:排除API、静态文件等无需处理的路径 export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], };
步骤2:安装依赖
中间件用到语言匹配工具库,执行以下命令安装:
npm install @formatjs/intl-localematcher negotiator
步骤3:优化语言切换函数(可选)
保留原切换逻辑,建议增加Cookie过期时间确保设置持久化:
import { useRouter } from 'next/router'; const handleSelectLanguage = (code) => { // 设置Cookie,有效期1年 document.cookie = `NEXT_LOCALE=${code};path=/;max-age=31536000`; // 跳转到对应语言的当前页面 router.push({ pathname: router.pathname, query: router.query }, undefined, { locale: code }); };
原理说明
- 中间件在请求到达页面之前拦截所有符合规则的路由,检查路径是否包含语言前缀。
- 若路径无语言前缀,优先读取
NEXT_LOCALECookie中的语言值,自动重定向到带对应语言前缀的路径。 - 即使用户直接输入无语言前缀的子页面URL(如
/about),中间件也会自动处理重定向,无需依赖组件内逻辑。
内容的提问来源于stack exchange,提问作者taske213123
相关产品推荐
相关产品推荐

