Next.js 14国际化:切换语言时如何保留searchParams?
解决Next.js 14 + next-intl切换语言丢失searchParams的问题
一、客户端组件的最佳实现方式
你用useSearchParams钩子修复的思路是标准可行的,以下是优化后的Header.tsx代码:
"use client" import { useTransition } from 'react' import { usePathname, useRouter, useSearchParams } from '@/navigation' export const Header = () => { const [isPending, startTransition] = useTransition(); const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const handleLanguageChange = (locale: string) => { startTransition(() => { // 传递当前查询参数到新路由,保留searchParams router.replace(pathname, { locale, searchParams }); }); } return ( <div> <button disabled={isPending} onClick={() => handleLanguageChange("de")} > DE </button> <button disabled={isPending} onClick={() => handleLanguageChange("en")} > ENG </button> </div> ) } export default Header
关键说明
useSearchParams获取当前URL的查询参数对象,直接传入router.replace即可完整保留所有参数startTransition用于避免路由切换时的UI卡顿,符合Next.js客户端路由的最佳实践
二、中间层(Middleware)的正确配置
你的现有middleware存在两个问题:一是导出了两个middleware函数(Next.js只会执行默认导出的逻辑),二是根路径重定向时未保留原查询参数。以下是修正后的代码:
import createMiddleware from 'next-intl/middleware'; import { cookies } from 'next/headers'; import { NextResponse, NextRequest } from 'next/server' // 初始化next-intl的核心中间件 const intlMiddleware = createMiddleware({ locales: ['en', 'de'], defaultLocale: 'de', }); export function middleware(request: NextRequest) { // 处理根路径重定向,保留原searchParams if (request.nextUrl.pathname === "/") { const locale = cookies().get("NEXT_LOCALE")?.value || "de"; const newUrl = new URL(`/${locale}`, request.url); // 直接复用原URL的查询参数 newUrl.search = request.nextUrl.search; return NextResponse.redirect(newUrl); } // 执行next-intl的默认中间件逻辑,处理带locale的路由 return intlMiddleware(request); } export const config = { matcher: [ '/', '/(de|en)/:path*', '/((?!_next|_vercel|.*\\..*).*)' ] }
关键说明
- 合并自定义逻辑与next-intl中间件,确保所有路由请求都经过完整处理
- 根路径重定向时,通过
request.nextUrl.search直接复用原查询参数,避免丢失 - next-intl的默认中间件会自动处理带locale的路由跳转,确保语言切换时(如通过URL参数或Cookie触发的重定向)保留searchParams
额外注意事项
- 使用
next-intl提供的Link组件时,默认会自动保留当前的searchParams,无需额外配置 - 确保
navigation.ts中的locales数组与middleware配置完全一致
内容的提问来源于stack exchange,提问作者xtreebug
相关产品推荐
相关产品推荐

