Next.js 13 App目录下如何移除URL中的语言前缀?
移除Next.js App目录+i18next的URL语言前缀方案
针对你的场景(英文、法文共享同一URL,无语言前缀),可以通过以下步骤实现:
1. 配置next-i18next与Next.js
修改next-i18next.config.js,核心是禁用URL语言前缀:
// next-i18next.config.js module.exports = { i18n: { defaultLocale: 'en', locales: ['en', 'fr'], localePrefix: 'never', // 关键:关闭URL路径中的语言前缀 }, localePath: './public/locales', // 翻译文件存放目录 };
在next.config.js中引入该配置:
// next.config.js const { i18n } = require('./next-i18next.config'); /** @type {import('next').NextConfig} */ const nextConfig = { i18n, // 其他项目配置 }; module.exports = nextConfig;
2. 初始化i18next并配置语言检测
先安装依赖包,用于通过Cookie和浏览器偏好检测语言:
npm install i18next-browser-languagedetector js-cookie
创建i18n.js初始化文件,配置语言检测优先级:
// i18n.js import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; import Cookies from 'js-cookie'; // 导入翻译文件(根据实际路径调整) const resources = { en: { translation: require('./public/locales/en/common.json'), }, fr: { translation: require('./public/locales/fr/common.json'), }, }; i18n .use(LanguageDetector) .use(initReactI18next) .init({ resources, fallbackLng: 'en', // 默认 fallback 为英文 interpolation: { escapeValue: false, // React已处理XSS,无需额外转义 }, detection: { order: ['cookie', 'navigator'], // 优先从Cookie读取语言,其次用浏览器默认语言 caches: ['cookie'], // 将用户选择的语言持久化到Cookie }, }); export default i18n;
3. 在Root Layout中注入I18nextProvider
修改app/layout.js,确保服务端和客户端都能正确识别当前语言:
// app/layout.js import { I18nextProvider } from 'react-i18next'; import i18n from '../i18n'; import { cookies } from 'next/headers'; export default async function RootLayout({ children }) { // 服务端从Cookie获取用户语言偏好 const cookieStore = cookies(); const userLang = cookieStore.get('i18next')?.value || 'en'; // 初始化服务端i18n语言 await i18n.changeLanguage(userLang); return ( <html lang={userLang}> <body> <I18nextProvider i18n={i18n}>{children}</I18nextProvider> </body> </html> ); }
4. 实现语言切换组件
创建客户端组件,用于切换语言并更新Cookie:
// components/LanguageSwitcher.js 'use client'; import { useTranslation } from 'react-i18next'; import Cookies from 'js-cookie'; import { useRouter } from 'next/navigation'; export default function LanguageSwitcher() { const { i18n } = useTranslation(); const router = useRouter(); const changeLanguage = (lng) => { // 更新Cookie持久化语言选择 Cookies.set('i18next', lng, { expires: 365 }); // 切换i18n语言 i18n.changeLanguage(lng); // 刷新页面让语言全局生效 router.refresh(); }; return ( <div className="language-switcher"> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('fr')}>Français</button> </div> ); }
关键注意事项
- 翻译文件需放在
public/locales目录下,比如en/common.json、fr/common.json,结构根据你的业务需求定义。 - 若涉及服务端数据请求(如
fetch或Server Components),可从Cookie中读取当前语言,请求对应语言的接口数据。 - SEO方面,需在页面中添加
hreflang标签,帮助搜索引擎识别多语言版本:
<link rel="alternate" hreflang="en" href="https://example.com" /> <link rel="alternate" hreflang="fr" href="https://example.com" /> <link rel="alternate" hreflang="x-default" href="https://example.com" />
内容的提问来源于stack exchange,提问作者u-bx31
相关产品推荐
相关产品推荐

