React和i18n-通过在URL中添加语言环境进行翻译
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React和i18n-通过在URL中添加语言环境进行翻译相关的知识,希望对你有一定的参考价值。
你好,我正在构建一个演示应用程序,只是为了学习React,而我对翻译过程还是有些执着。我想做的是建立一个多语言网站,默认语言为“希腊语”,第二语言为“英语”。启用希腊语后,URL中不应包含任何语言环境,但使用英语时,应使用/ en /重写URL。
i18n Config
import translationEn from './locales/en/translation';
import translationEl from './locales/el/translation';
import Constants from './Utility/Constants';
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: 'el',
debug: true,
ns: ['translations'],
defaultNS: 'translations',
detection: {
order: ['path'],
lookupFromPathIndex: 0,
},
resources: {
el: {
translations: translationEl
},
en: {
translations: translationEn
}
},
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
}
}, () => {
// Why the fuck this doesnt work automatically with fallbackLng ??
if (!Constants.allowed_locales.includes(i18n.language)) {
i18n.changeLanguage(Constants.default_locale);
}
return;
});
i18n.on('languageChanged', function (lng) {
// if somehow it get injected
if (!Constants.allowed_locales.includes(i18n.language)) {
i18n.changeLanguage(Constants.default_locale);
}
// if the language we switched to is the default language we need to remove the /en from URL
if (Constants.default_locale === lng) {
Constants.allowed_locales.map((item) => {
if (window.location.pathname.includes("/" + item)) {
let newUrl = window.location.pathname.replace("/" + item, "");
window.location.replace(newUrl);
}
})
} else { // Add the /en in the URL
// @todo: add elseif for more than 2 langs because this works only for default + 1 more language
let newUrl = "/" + lng + window.location.pathname;
window.location.replace(newUrl);
}
});
export default i18n;
我将Language Detector
插件与path一起使用,因此它可以从URL解析语言环境。现在,没有初始化时添加的回调函数,如果URL为LanguageDetector
或www.example.com/en/
或www.example.com/el
,则www.example.com/en/company
将正确设置语言。但是,如果我直接访问了www.example.com/company
(在第一次访问房屋之前,将设置语言环境),i18n会将语言环境/语言设置为"company"
!!!
fallbackLng
有一个选项,我认为如果LanguageDetector
未检测到它,它将把语言设置为您配置的语言,但是似乎没有选项将可用语言或默认语言设置为i18n(或我是个白痴,找不到它),所以LanguageDetector设置了他在URL中找到的任何内容。为了解决这个问题,我在上面添加了一个Constants文件和回调函数。
Contants.js
const Constants = {
"allowed_locales": ['el','en'],
"default_locale": 'el'
}
export default Constants;
[我还添加了一个事件处理程序,该事件处理程序在LanguageChange上触发,因此如果英语处于活动状态,它将使用/ en /重写URL,如果希腊语是则删除/ el /。
index.js
ReactDOM.render(
<BrowserRouter>
<I18nextProvider i18n={i18n}>
<App/>
</I18nextProvider>
</BrowserRouter>
,
document.getElementById('root')
);
App.js
class App extends React.Component {
render() {
return (
<div className="App">
<Suspense fallback="loading">
<Header {...this.props}/>
<Routes {...this.props} />
</Suspense>
</div>
);
}
}
export default withTranslation('translations')(App);
index.js和App.js没什么特别的
Header Component
class Header extends React.Component {
linkGenerator(link) {
// if the current language is the default language dont add the lang prefix
const languageLocale = this.props.i18n.options.fallbackLng[0] === this.props.i18n.language ? null : this.props.i18n.language;
return languageLocale ? "/" + languageLocale + link : link;
}
render() {
return (
<div className="header">
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand className="logo" href="/"> <Image src="/assets/logo.png" rounded/>
</Navbar.Brand>
{/*Used For Mobile Navigation*/}
<Navbar.Toggle aria-controls="basic-navbar-nav"/>
<Navbar.Collapse id="basic-navbar-nav" className="float-right">
<Nav className="ml-auto">
<Nav.Link as={NavLink} exact to={this.linkGenerator("/")}>{this.props.t('menu.home')}</Nav.Link>
<Nav.Link as={NavLink} to={this.linkGenerator("/company")}>{this.props.t('menu.company')}</Nav.Link>
</Nav>
<Nav className="mr-auto">
{this.props.i18n.language !== "el" ? <button onClick={() => this.props.i18n.changeLanguage('el')}>gr</button>
: null}
{this.props.i18n.language !== "en" ? <button onClick={() => this.props.i18n.changeLanguage('en')}>en</button>
: null}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</div>
)
}
}
export default Header
为了使用语言环境创建菜单的URL,我创建了linkGenerator function
最后,在处理所有路由的Routes组件中,我在实际的url之前添加了一个常量,因此它将适用于所有这些/page
,/el/page
,/en/page
路由组件
import React from 'react';
import {Switch, Route} from 'react-router-dom';
import CompanyPage from './Pages/CompanyPage';
import HomePage from './Pages/HomePage';
import NotFound from './Pages/NotFound';
class Routes extends React.Component {
render() {
const localesString = "/:locale(el|en)?";
return (
<Switch>
<Route exact path={localesString + "/"} component={HomePage}/>
<Route path={localesString + "/company"} component={CompanyPage}/>
<Route component={NotFound}/>
</Switch>
);
}
}
export default Routes
代码以某种方式起作用,但充满了诸如:]之类的hacks
额外的配置文件(constants.js)
回调函数,将语言从“公司”更改为默认语言环境。 (这将触发2页重新加载)
用于处理菜单和路线中的语言环境的功能
等。
是否有任何“内置”功能或更好的方法才能在没有上述hack的情况下实现同一目标?
你好,我正在构建一个演示应用程序,只是为了学习React,而我对翻译过程还是有些执着。我想做的是使用默认语言为“希腊语”的多语言网站...
我需要同样的东西,我发现您可以设置i18n.init选项的whitelist
属性并指定支持的语言。之后,如果在checkWhitelist: true
选项中设置detection
,则LanguageDetector
以上是关于React和i18n-通过在URL中添加语言环境进行翻译的主要内容,如果未能解决你的问题,请参考以下文章