Next.js多语言网站语言切换与路由配置问题求助
解决方案
1. 修复语言切换器
当前切换器仅跳转根路径,且未处理当前页面的路径映射。修改组件以保留当前路径并生成对应语言的链接:
'use client'; import Link from "next/link"; import { usePathname } from "next/navigation"; export default function LanguageSwitcher() { const pathname = usePathname(); // 提取当前路径中的locale(如果存在) const currentLocale = pathname.split('/')[1]; // 去掉路径中的locale前缀,得到基础路径 const basePath = currentLocale && ['en', 'nl', 'fr'].includes(currentLocale) ? pathname.slice(`/${currentLocale}`.length) || '/' : pathname; return ( <ul> <li><Link href={basePath} locale="en">EN</Link></li> <li><Link href={basePath} locale="nl">NL</Link></li> <li><Link href={basePath} locale="fr">FR</Link></li> </ul> ); }
同时在next.config.js中配置i18n:
/** @type {import('next').NextConfig} */ const nextConfig = { i18n: { locales: ['en', 'nl', 'fr'], defaultLocale: 'nl', localeDetection: false, // 禁用自动检测,由middleware接管 }, }; module.exports = nextConfig;
2. 修复未知语言路径的重定向问题
原middleware未识别路径中的无效locale,导致错误追加默认前缀。修改middleware逻辑:
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { match } from '@formatjs/intl-localematcher'; import Negotiator from 'negotiator'; const locales = ['en', 'nl', 'fr']; const defaultLocale = 'nl'; // 从请求头获取用户偏好语言 function getLocale(request: NextRequest): string { const headers = { 'accept-language': request.headers.get('accept-language') || '' }; const languages = new Negotiator({ headers }).languages(); return match(languages, locales, defaultLocale); } export default function middleware(request: NextRequest) { const pathname = request.nextUrl.pathname; const pathLocale = pathname.split('/')[1]; // 处理无效locale路径(如/de/contact) if (pathLocale && !locales.includes(pathLocale)) { const validPath = pathname.slice(`/${pathLocale}`.length) || '/'; return NextResponse.redirect(new URL(validPath, request.url)); } // 处理无locale前缀的路径 const pathnameIsMissingLocale = locales.every( (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}` ); if (pathnameIsMissingLocale) { const locale = getLocale(request); // 偏好语言为默认语言时,直接访问无前缀路径 if (locale === defaultLocale) return NextResponse.next(); // 非默认语言,重定向到带前缀路径 return NextResponse.redirect(new URL(`/${locale}${pathname || '/'}`, request.url)); } // 处理默认语言前缀路径(如/nl/contact),重定向到无前缀路径 if (pathLocale === defaultLocale) { const newPath = pathname.slice(`/${defaultLocale}`.length) || '/'; return NextResponse.redirect(new URL(newPath, request.url)); } return NextResponse.next(); } export const config = { matcher: ['/((?!_next|api|static).*)'], // 跳过内部资源和API路径 };
3. 配置默认语言无前缀路由
调整目录结构配合上述配置:
- 将默认语言(nl)的页面放在
app/根目录下(如app/page.tsx、app/contact/page.tsx) - 将其他语言的页面放在对应子目录中(如
app/en/page.tsx、app/fr/contact/page.tsx)
最终效果:
site.com/、site.com/contact直接加载nl语言内容site.com/nl/contact会自动重定向到site.com/contactsite.com/en/contact加载en语言内容
内容的提问来源于stack exchange,提问作者Alnedru
相关产品推荐
相关产品推荐

