国际化(i18n)是指让应用程序能够适应不同语言和地区的过程。简单来说,就是让一个应用可以轻松切换成多种语言版本,同时还要处理好日期、时间、货币等格式的差异。
文字翻译
这是最基本的需求。界面上所有显示的文字,包括按钮、标题、提示信息,都需要根据用户选择的语言来显示对应版本。
日期和时间格式
不同地区的日期格式差别很大。比如:
中国:2025年4月29日
美国:04/29/2025
欧洲:29/04/2025
货币和数字格式
货币符号和数字分隔符各不相同:
中国:¥1,000.00
美国:$1,000.00
欧洲:1.000,00€
阅读方向
有些语言是从右向左阅读的,比如阿拉伯语、希伯来语。这时候整个页面布局都需要镜像翻转。
时区处理
显示时间时要考虑用户所在的时区,特别是涉及活动时间、消息时间等场景。
i18next + react-i18next
这是目前最流行的方案。i18next 功能全面,react-i18next 专门为 React 做了优化。
主要特点:
支持动态加载翻译文件
自动检测用户浏览器语言
处理各种格式的本地化
支持 RTL 语言
适合:中大型项目,需要完整国际化功能的场景。
react-intl
由 FormatJS 团队开发,专注于格式化功能。
主要特点:
强大的日期、数字、货币格式化
组件化设计,使用简单
api 直观易用
适合:中小型项目,主要需要格式化功能的场景。
Polyglot.js
轻量级解决方案,功能相对简单。
主要特点:
代码量小,打包体积小
API 简单,上手快
只提供基础翻译功能
适合:小型项目或原型开发。
下面我们通过一个具体例子,展示如何在 Next.js 应用中实现多语言切换。
首先安装需要的包:
pnpm add i18next i18next-browser-languagedetector i18next-http-backend react-i18next
创建翻译文件。在 public 目录下建立这样的文件结构:
public/
locales/
en/
common.json
zh/
common.json
英文翻译文件 (locales/en/common.json):
{
"welcome": "Welcome to our application",
"description": "This is a demo of internationalization"
}
中文翻译文件 (locales/zh/common.json):
{
"welcome": "欢迎使用我们的应用",
"description": "这是国际化的演示"
}
创建 i18n 配置文件 (src/i18n.ts):
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: "en",
debug: process.env.NODE_ENV === 'development',
interpolation: {
escapeValue: false,
},
backend: {
loadPath: "/locales/{{lng}}/{{ns}}.json",
},
});
export default i18n;
创建国际化 Provider (src/components/I18nProvider.tsx):
"use client";
import { I18nextProvider } from "react-i18next";
import i18n from "@/i18n";
import { ReactNode } from "react";
interface Props {
children: ReactNode;
}
export default function I18nProvider({ children }: Props) {
return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>;
}
创建语言切换组件 (src/components/LanguageSwitcher.tsx):
"use client";
import { useTranslation } from "react-i18next";
export default function LanguageSwitcher() {
const { i18n } = useTranslation();
const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
};
return (
<div className="flex gap-2">
<button
onClick={() => changeLanguage("en")}
disabled={i18n.resolvedLanguage === "en"}
className="px-3 py-1 border rounded disabled:opacity-50"
>
English
</button>
<button
onClick={() => changeLanguage("zh")}
disabled={i18n.resolvedLanguage === "zh"}
className="px-3 py-1 border rounded disabled:opacity-50"
>
中文
</button>
</div>
);
}
在根布局中包裹 Provider (src/app/layout.tsx):
import I18nProvider from "@/components/I18nProvider";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<I18nProvider>
{children}
</I18nProvider>
</body>
</html>
);
}
在页面中使用翻译 (src/app/page.tsx):
"use client";
import { useTranslation } from "react-i18next";
import LanguageSwitcher from "@/components/LanguageSwitcher";
export default function Home() {
const { t } = useTranslation("common");
return (
<div className="min-h-screen p-8">
<div className="flex items-center gap-4">
<h1 className="text-2xl font-bold">{t("welcome")}</h1>
<LanguageSwitcher />
</div>
<p className="mt-4">{t("description")}</p>
</div>
);
}
国际化不只是简单翻译,还要处理一些复杂情况:
{
"message_count": "{{count}} 条消息",
"message_count_plural": "{{count}} 条消息",
"welcome_user": "欢迎,{{name}}!"
}
在组件中使用:
const { t } = useTranslation("common");
// 复数形式
t('message_count', { count: 1 }); // "1 条消息"
t('message_count', { count: 5 }); // "5 条消息"
// 插值
t('welcome_user', { name: '张三' }); // "欢迎,张三!"
除了文字翻译,我们还需要格式化日期、时间、货币等:
import { useTranslation } from 'react-i18next';
function ProductCard({ price, date }) {
const { i18n } = useTranslation();
const formattedPrice = new Intl.NumberFormat(i18n.language, {
style: 'currency',
currency: 'CNY'
}).format(price);
const formattedDate = new Intl.DateTimeFormat(i18n.language).format(date);
return (
<div>
<p>价格: {formattedPrice}</p>
<p>日期: {formattedDate}</p>
</div>
);
}
保持翻译文件结构化
按功能模块组织翻译文件,避免一个文件过大。
使用命名空间
// 在 i18n 配置中设置多个命名空间
i18n.init({
defaultNS: 'common',
ns: ['common', 'dashboard', 'settings']
});
// 使用时指定命名空间
t('dashboard:title');
处理动态加载
对于大型应用,可以按需加载翻译文件:
// 动态导入翻译文件
import(`../locales/${lng}/${ns}.json`).then((resources) => {
i18n.addResourceBundle(lng, ns, resources);
});
测试所有语言
确保每种语言的界面都正常显示,特别是长文字和 RTL 语言。
考虑可访问性
语言切换时,要正确设置 html 的 lang 属性:
useEffect(() => {
document.documentElement.lang = i18n.language;
}, [i18n.language]);
在 React 中实现国际化其实并不复杂。选择适合的方案,按照步骤配置,就能让应用支持多语言。关键是要提前规划好翻译文件的结构,处理好各种边界情况。
对于大多数项目,i18next + react-i18next 是比较推荐的选择。它功能全面,社区活跃,遇到问题容易找到解决方案。如果是小型项目,可以考虑更轻量级的方案。
国际化不仅是技术实现,还需要考虑用户体验。好的国际化实现能让全球用户都感受到贴心的使用体验。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!
internationalization (国际化)简称:i18n,因为在i和n之间还有18个字符,localization(本地化 ),简称L10n。 一般用语言_地区的形式表示一种语言,如:zh_CN表示简体中文
一般来讲,要翻译的文字比较多,所以最好为每门语言建立独立文件管理. 新建文件 lang/zh.js、 lang/en.js, 写入一些测试数据,下面去封装一个组件,用来切换语言,并将语言状态保存到cookie和Vuex中。
有些项目我们需要支持多种语言切换,满足国际化需求。 vue-i18n是一个vue插件,主要作用就是让项目支持国际化多语言,使用方便快捷,能很轻松的将我们的项目国际化。本文主要介绍使用vue-i18n实现切换中英文效果。
新建目录结构如下:assets/langs/index.js内容如下:loadLanguageAsync是实际用于更改语言的函数。比如在路由钩子中获取到当前语言环境加载对应语言包
我遇到过一些人,他们根本不认为CSS与国际化有关,但如果你仔细想想,国际化不仅仅是把你网站上的内容翻译成多种语言,然后就收工了。该内容的呈现方式有各种细微的差别,这些细微的差别会影响到母语人士使用您的网站的体验。
你的网站需要支持多语言用户吗?Vue.js让国际化变得非常简单。本文将手把手教你如何实现。利用vue-i18n库,你可以高效地为Vue应用添加Vue国际化功能。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!