我已经用 i18next 翻译了我的 React 组件。当我切换语言时,如何使用react-router为localhost:3000/en这样路由它?例如,当我切换到瑞典语时,它应该自动切换到 /se。
App.jsx 和我的路线 =>
<ThemeProvider defaultTheme='light' storageKey='vite-ui-theme'>
<SelectedContext.Provider value={{ selected, setSelected }}>
<UserContext.Provider value={{ user, setUser }}>
<Toaster />
<Elements stripe={stripePromise}>
<Router>
<div className='w-screen'>
<LoadingBarComponent />
{/* Render the appropriate component based on the route */}
<Navigation userProfile={userProfile}/>
<Routes>
<Route path='*' element={<ErrorPage />} />
<Route path="/" element={<Home userPlan={userPlan} stripeID={stripeID} />} />
<Route path='/terms' element={<Terms />} />
<Route path='/create' element={<Dashboard userPlan={userPlan} userProfile={userProfile} />} />
<Route path='/create/add' element={<Create userPlan={userPlan} />} />
<Route path='/create/tag/:category' element={<Dubs />} />
<Route path='/Signup' element={<Signup />} />
<Route path='/login' element={<Login />} />
<Route path='/reset-password' element={<ResetPass />} />
<Route path='/reset-password/reset' element={<NewPassword />} />
<Route path='/pricing' element={<Pricing stripeID={stripeID} userPlan={userPlan} />} />
<Route path='/credits' element={<Credits credits={credits} setCredits={setCredits} stripeID={stripeID} />} />
<Route path='/create/editor/:voiceName' element={<Editor user={user} credits={credits} setCredits={setCredits} userPlan={userPlan} />} />
<Route path='/success/confirm' element={<ConfirmEmail />} />
<Route path='/payment/success' element={<PaymentSuccess />} />
<Route path='/billing' element={<Billing user={user} userPlan={userPlan} stripeID={stripeID} />} />
<Route path='/create/search' element={<SearchMobile />} />
<Route path='/login-popup' element={<LoginPopup />} />
<Route path='/voices' element={<MyVoices user={user} userPlan={userPlan} />} />
<Route path='/profile/settings' element={<SettingsPage />} />
</Routes>
<FooterComponent />
</div>
</Router>
</Elements>
</UserContext.Provider>
</SelectedContext.Provider>
</ThemeProvider>
Footer.jsx,我在其中切换语言 =>
const Footer = () => {
const navigate = useNavigate();
const [language, setLanguage] = useState(navigator.language.slice(0,2) || "en");
const languageSum = {
en: "English",
sv: "Swedish"
}
const getLanguage = (language) => {
return languageSum[language]
}
const openInNewTab = (url) => {
window.open(url, "_blank", "noreferrer");
};
const handleLanguageClick = (language) => {
i18next.changeLanguage(language);
setLanguage(language);
console.log("set language", language);
};
return (
<div className="pt-[160px]">
<div className="pt-[160px]">
<Separator />
</div>
<div id="footer-container" className="pt-[35px] flex flex-row space-x-2 justify-center">
<div className="flex flex-col space-y-1">
<div className="flex-row flex space-x-1">
<div id="footer-text" className="flex items-center">
<img id="footer-logo" src={Logo} className="w-[25px] h-[25px]" alt="logo"></img>
<h2 id="footer-name" className="text-xl font-semibold">VoiceOvery</h2>
<DropdownMenu>
<DropdownMenuTrigger>
<Button>
<Globe className="mr-1" /> {getLanguage(language)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>Languages</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => handleLanguageClick("en")}>English</DropdownMenuItem>
<DropdownMenuItem>German</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleLanguageClick("sv")}>Swedish</DropdownMenuItem>
<DropdownMenuItem>Spanish</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
这是我的 i18next 配置 =>
const options = {
order: ['querystring', 'navigator'],
lookupQuerystring: 'lng'
}
i18next
.use(initReactI18next)
// Initialize the i18next instance.
.init({
// Default langauge
detection: options,
lng: navigator.language || "en",
// Fallback language
fallbackLng: "en",
debug: true,
interpolation: {
escapeValue: false,
},
resources: {
en: {
translation: {
...landingEn,
...faqEn,
...pricingEn,
...loginEn,
...metaEn,
...categoriesEn
}
},
sv: {
translation: {
...landingSe,
...faqSe,
...pricingSe,
...loginSe,
...metaSe,
...categoriesSe
}
}
}
});
任何帮助将不胜感激!似乎无法弄清楚。我试过了
要使用
react-router
和 i18next
在 React 中实现语言路由,您可以执行以下操作:
基于语言的路由配置: 定义一个包装器或策略来为所有路由添加语言代码。
语言切换器: 在语言切换器(在
Footer.jsx
中)中实现逻辑,以便能够使用当前语言代码更新 URL。
语言检测器: 使用从 URL 读取语言的语言检测器改进
i18next
的配置。
创建组件以使用语言代码为路由添加前缀:
// higher-order component that wraps a given component with a language route
const withLanguageRoutes = (Component, path, exact = false) => {
return (
<Route
path={`/:lng${path}`}
element={props => <Component {...props} />}
exact={exact}
/>
);
};
然后将所有路线包装在
withLanguageRoutes
HOC 中:
<Routes>
{withLanguageRoutes(Home, "/")}
...
{/* Repeat for other routes */}
</Routes>
更新
handleLanguageClick
中的 Footer.jsx
以更改语言以及包含语言代码的 URL。
const handleLanguageClick = (language) => {
i18next.changeLanguage(language);
setLanguage(language);
navigate(`/${language}`); // This navigates to the language-specific path
};
实现自定义语言检测器:
const detectionOptions = {
// ... other options
order: ['path', 'querystring', 'navigator'],
lookupFromPathIndex: 0,
};
i18next
.use(initReactI18next)
// possibly use a custom detector or add the 'path' to detectors
.use(LanguageDetector) // Ensure to have the language detector
.init({
detection: detectionOptions,
// ... other i18next init options
});
现在,当用户单击页脚中的语言选项时,应用程序应该更新 URL 以包含所选的语言代码,并且 i18next 应该检测到更改以加载适当的翻译。
react-router
路由也将在 URL 中反映新语言。