我将 i18next 与 React 结合使用,并拥有三种语言文件(阿拉伯语、英语和法语)。目前,当用户请求该网站时,我正在加载所有三个翻译文件,这感觉最初发送的数据太多。虽然它具有在用户切换语言时即时翻译的优点,但我想探索实现延迟加载翻译的可能性,以最初仅加载一个翻译文件,然后在用户更改语言时加载其他文件,只需简单的加载屏幕。
这是我的 i18n.ts 文件:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';
import en from '/public/locales/en/translation.json'
import fr from '/public/locales/fr/translation.json'
import ar from '/public/locales/ar/translation.json'
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
debug: true,
fallbackLng: 'en',
interpolation: {
escapeValue: false,
},
resources: {
en: {
translation: en
},
fr: {
translation: fr
},
ar: {
translation: ar
}
}
});
export default i18n;
这是我的语言切换组件:
/* eslint-disable no-alert, no-console */
import i18n from "i18next";
import { Globe2 } from "lucide-react";
import React from "react";
import { useTranslation } from "react-i18next";
import { Button } from "./ui/button";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./ui/dropdown-menu";
import { cn } from "@/lib/utils";
interface Language {
label: string;
dir: "ltr" | "rtl";
active: boolean;
}
const lngs: Record<string, Language> = {
en: { label: "English", dir: "ltr", active: true },
ar: { label: "العربية", dir: "rtl", active: false },
fr: { label: "Français", dir: "ltr", active: false },
};
function LanguageToggle({ className }: { className: string }) {
const storedLanguage = localStorage.getItem("i18nextLng") || "en";
const selected = Object.keys(lngs).find((lng) => storedLanguage.startsWith(lng)) || "en";
const { t } = useTranslation();
const [menuAnchor,] = React.useState(null);
React.useEffect(() => {
document.body.dir = lngs[selected].dir;
}, [menuAnchor, selected]);
return (
<div className={cn(className)} >
<DropdownMenu >
<DropdownMenuTrigger asChild className="cursor-pointer" >
<Button style={{ paddingBlock: "19px" }} className="" variant="outline" size="sm">
<span className="me-2" >{t('language')} </span><Globe2 />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{Object.keys(lngs).map((lng) => (
<DropdownMenuItem className="cursor-pointer" key={lng} onClick={() => {
i18n.changeLanguage(lng)
}}>
{lngs[lng].label}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</div>
)
}
export default LanguageToggle
是否可以在此设置中实现延迟加载翻译,以提高初始加载性能,同时为用户保持流畅的语言切换体验?如果是这样,我怎样才能实现这一目标?
我尝试使用 i18next 在我的 React 应用程序中实现延迟加载翻译。我期望的是,一开始只会加载一个翻译文件,当用户更改语言时,会加载相应的翻译文件并带有加载屏幕,从而提高初始加载性能。
在我的实现中,我遵循标准 i18next 设置,如我的代码所示。但是,我不确定如何实现如上所述的翻译延迟加载。我正在寻找有关最佳实践或代码示例的指导,以有效地实现此功能。
有时间回答这个问题 - 我最近从事一个商业项目,需要延迟加载语言环境文件。
除了我在评论部分写的上述链接之外,下面的解决方案也适用于它(这也是由
i18next-resources-to-backend
指南建议的):
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import ChainedBackend from "i18next-chained-backend";
import HttpBackend from "i18next-http-backend";
import resourcesToBackend from 'i18next-resources-to-backend';
i18n
.use(ChainedBackend)
.use(initReactI18next)
.init({
lng: 'en', // default language
fallbackLng: 'en',
defaultNS: 'translation', // default namespace, if you don't want to specify it in JS files every time.
interpolation: {
escapeValue: false,
},
backend: {
backends: [
HttpBackend, // if you need to check translation files from server
resourcesToBackend((language, namespace) => import(`../locales/${language}/${namespace}.json`))
], // the most important part that allows you to lazy-load translations
backendOptions: [{
loadPath: 'http://localhost:4000/locales/{{lng}}/{{ns}}.json'
}]
}
});
export default i18n;
如果您需要进一步的解释,请告诉我。希望解决方案有所帮助。