Next.js页面加载时如何根据查询参数切换Locale?
Next.js 通过查询参数切换Locale的最优实现方案
核心思路
通过全局Middleware拦截所有请求,自动处理?local=xx查询参数,验证合法性后切换至目标Locale并持久化,全程无需在页面级编写重复逻辑,是符合Next.js框架设计的最优方案。
步骤1:配置多语言基础支持
在项目根目录的next.config.js中定义允许的Locale列表与默认语言:
/** @type {import('next').NextConfig} */ const nextConfig = { i18n: { locales: ['zh-CN', 'en', 'ja'], // 替换为你需要支持的语言标识 defaultLocale: 'zh-CN', // 设置默认语言 }, } module.exports = nextConfig
步骤2:编写全局Middleware处理参数
创建middleware.js(或.ts)文件,全局拦截非静态资源的请求,处理查询参数并持久化Locale:
import { NextResponse } from 'next/server' // 与next.config.js中的locales保持一致 const ALLOWED_LOCALES = ['zh-CN', 'en', 'ja'] export function middleware(request) { const url = request.nextUrl.clone() const { searchParams } = url const targetLocale = searchParams.get('local') // 处理合法的Locale查询参数 if (targetLocale && ALLOWED_LOCALES.includes(targetLocale)) { // 重定向到带Locale前缀的规范路由,移除查询参数 url.pathname = `/${targetLocale}${url.pathname}` searchParams.delete('local') url.search = searchParams.toString() // 设置官方认可的NEXT_LOCALE Cookie,持久化用户选择 const response = NextResponse.redirect(url) response.cookies.set('NEXT_LOCALE', targetLocale, { maxAge: 30 * 24 * 60 * 60, // 30天有效期 path: '/', secure: process.env.NODE_ENV === 'production', // 生产环境启用HTTPS }) return response } // 自动应用Cookie中保存的Locale(若未在路由前缀中) const cookieLocale = request.cookies.get('NEXT_LOCALE')?.value if ( cookieLocale && ALLOWED_LOCALES.includes(cookieLocale) && !url.pathname.startsWith(`/${cookieLocale}`) ) { url.pathname = `/${cookieLocale}${url.pathname}` return NextResponse.redirect(url) } return NextResponse.next() } // 指定Middleware生效范围,排除静态资源与API export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], }
步骤3:页面中获取当前Locale
App Router(Next.js 13+)
直接使用框架内置的useLocale钩子获取当前语言:
'use client' import { useLocale } from 'next/navigation' export default function HomePage() { const currentLocale = useLocale() return <div>当前语言:{currentLocale}</div> }
Pages Router(旧版本)
通过useRouter钩子获取Locale:
import { useRouter } from 'next/router' export default function HomePage() { const { locale } = useRouter() return <div>当前语言:{locale}</div> }
关键优势
- 全局统一处理:Middleware覆盖所有页面请求,避免页面级重复代码
- 符合框架规范:采用Next.js官方支持的Locale前缀路由与
NEXT_LOCALECookie,兼容性拉满 - URL干净美观:自动移除查询参数,保持路由结构规范
- 安全可靠:仅允许配置过的合法Locale,防止非法参数导致异常
内容的提问来源于stack exchange,提问作者Marius
相关产品推荐
相关产品推荐

