在 React 里面实现国际化实现是太简单了 🙂‍↔️🙂‍↔️🙂‍↔️

面试导航 是一个专注于前、后端技术学习和面试准备的 免费 学习平台,提供系统化的技术栈学习,深入讲解每个知识点的核心原理,帮助开发者构建全面的技术体系。平台还收录了大量真实的校招与社招面经,帮助你快速掌握面试技巧,提升求职竞争力。如果你想加入我们的交流群,欢迎通过微信联系:yunmz777

国际化(Internationalization,简称 i18n)是指通过为应用程序设计一个可扩展的框架,使其能够无缝适应不同语言和地区环境。这一过程的目标是确保产品能够在不需要重新开发的情况下,支持多种语言、地区格式和文化习惯,从而为全球用户提供一致的体验。

与国际化紧密相关的是本地化(Localization,简称 l10n)。两者的关系可以简单概括为:

  • 国际化(i18n):为支持多语言、多地区打下基础,使应用能够灵活适应不同市场需求。

  • 本地化(l10n):具体实现语言翻译和地区适配,确保产品符合特定文化和市场的要求。

在前端开发中,国际化主要涵盖以下几个方面:

  1. 文本的多语言支持:页面上的文字、按钮、提示信息和表单验证等内容,需要根据用户的语言设置动态显示,从而确保全球用户都能轻松理解。

  2. 日期、时间、数字、货币格式的适配

    • 日期格式:例如,中国使用2025/04/29,美国则是04/29/2025

    • 货币格式:中国的货币表示为¥1000.00,而美国是$1,000.00

    • 数字格式:不同地区采用不同的千分位分隔符(如,.)。

  3. 右到左(RTL)语言支持:对于阿拉伯语、希伯来语等从右向左书写的语言,页面布局和文本方向需要做相应调整,以符合用户的阅读习惯。

  4. 时区和本地时间显示:显示本地时间而非服务器时间至关重要,特别是在涉及活动时间、消息发送时间等场景时,需要根据用户所在的时区进行调整,确保时间信息的准确性。

国际化方案

接下来我们将介绍一些国际化的方案

1. i18next + react-i18next

i18next 是一个非常流行的国际化库,它不仅支持多语言切换,还能处理日期、时间、数字、货币等本地化需求。通过 react-i18next,它能完美集成到 React 应用中,提供以下特点:

  • 动态加载翻译资源:无需将所有翻译文件打包到前端,可以按需从服务器加载翻译资源,减少了前端包的体积。

  • 自动语言检测:通过 i18next-browser-languagedetector,它可以根据用户的浏览器语言自动切换语言,无需额外操作。

  • 丰富的功能支持:除了支持多语言切换,它还可以处理日期、数字、货币等格式的本地化需求,甚至支持右到左(RTL)语言(如阿拉伯语、希伯来语)的布局调整。

适用场景:这套方案适用于中大型应用,尤其是那些需要支持多语言、动态加载翻译文件、并且需要处理复杂格式化(如日期、时间、货币)的项目。

2. react-intl

react-intl 是由 FormatJS 团队开发的库,它主要专注于格式化功能,尤其是日期、时间、数字和货币等内容的本地化。其特点包括:

  • 专注于格式化:react-intl 提供了强大的日期、时间、货币、数字等格式化功能,适用于有这些需求的项目。

  • 简化的 API:通过 IntlProvider 组件,开发者可以轻松设置和切换语言,并且提供了 FormattedMessageFormattedNumberFormattedDate 等组件来处理格式化内容。

  • 组件化设计:集成到 React 应用时,react-intl 的组件化设计可以让翻译和格式化工作变得非常直观,支持直接在组件中进行国际化处理。

适用场景:react-intl 适用于需要高效本地化格式化的中小型项目,尤其是那些需要处理日期、时间、数字、货币等格式的应用。它更适合那些需要简洁、易用的 API 的项目。

3. Polyglot.js

Polyglot.js 是一个轻量级的国际化库,适用于小型项目或者需求相对简单的应用。它提供了基本的文本翻译和语言切换功能,但功能相对简单:

  • 轻量级:Polyglot.js 的代码量非常小,依赖较少,适合小型项目,特别是那些不需要复杂本地化处理的项目。

  • 简易实现:它的 API 很简单,只需要提供语言文件并进行简单的语言切换操作,开发者可以快速实现国际化功能。

  • 限制功能:由于它主要聚焦在文本翻译上,对于日期、时间、数字等本地化需求的支持比较有限。

适用场景:Polyglot.js 非常适合小型应用或简单的项目,尤其是当只需要实现基础的文本翻译功能时,适合开发快速原型或小型产品。

4. formatjs

formatjs 是一个低层次的本地化库,它提供了更多底层的格式化能力。react-intl 就是基于 formatjs 构建的,如果你的项目有更复杂的国际化需求,可以直接使用 formatjs

  • 高度定制化:formatjs 提供了大量的 API,可以帮助开发者根据项目的需求进行灵活定制,特别适用于需要高度自定义本地化流程的项目。

  • 支持复杂格式化:它支持日期、时间、货币、数字等格式化,还允许开发者根据特定的需求自定义格式。

  • 低级别操作:提供的 API 更加底层,能够为开发者提供更多的控制,但也需要更多的配置。

适用场景:formatjs 适合需要高度定制化的应用,或者在复杂本地化需求下,开发者希望控制更细节部分的项目。

5. Localized-React

Localized-React 是一个相对较简单的国际化库,适用于一些小型或快速开发的项目。它的特点是:

  • 简单易用:提供基础的国际化功能,支持文本翻译和语言切换,且不需要复杂的配置。

  • 快速实现:Localized-React 可以帮助开发者快速将国际化集成到项目中,适合快速开发和 MVP(最小可行产品)开发。

  • 功能有限:它并不支持像 i18nextreact-intl 那样复杂的格式化需求(如日期、货币格式化等),更侧重于基本的文本翻译和语言切换。

适用场景:Localized-React 非常适合快速构建的中小型项目,特别是那些不需要动态加载翻译资源、复杂格式化功能的应用。

小结

i18next + react-i18next 适合中大型应用,能够支持多语言切换、动态加载翻译文件,并处理复杂的本地化需求,如日期、时间和货币等格式化。react-intl 则更适合中小型项目,它专注于日期、时间、货币等格式化功能,提供简洁易用的 API,便于快速集成。对于轻量级应用,Polyglot.js 是一个不错的选择,它提供基本的文本翻译功能,代码量小,非常适合快速开发。formatjs 适用于需要高度定制化本地化功能的复杂应用,它提供更多底层控制,能满足复杂的国际化需求。最后,Localized-React 非常适合快速开发的小型项目,满足基本翻译需求且配置简单。根据项目的需求、规模和复杂度,可以选择最合适的国际化方案。

如何在 React 中实现

接下来我们将会在 NextJs 项目中实现这样的效果,并且我们使用的是 App Router 进行讲解。

首先我们需要安装的几个包:

bash 复制代码
pnpm add i18next i18next-browser-languagedetector i18next-http-backend react-i18next

安装完成之后,我们可以再 public 目录下创建一个 locales 目录,并且根据不同语言创建不同的文件:

我们现在只做了英文和中午的,在这里只做了一个内容的翻译的:

目前这些我们只做了中文和英文的。

接下来我们要进入到项目中配置了,首先在 src 目录下创建一个 i18n.ts 文件并编写如下代码:

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: true,
    interpolation: {
      escapeValue: false,
    },
    backend: {
      loadPath: "/locales/{{lng}}/{{ns}}.json",
    },
  });

export default i18n;

这段代码配置了 i18next 用于支持 React 应用的国际化功能。它首先引入了必要的模块,包括 i18nextreact-i18nexti18next-browser-languagedetector(一个用于自动检测用户语言的插件)以及 i18next-http-backend(一个用于通过 HTTP 加载翻译资源的插件)。接着,代码调用 .use() 方法将这些插件应用到 i18next 实例中,并通过 .init() 方法初始化配置。

在初始化过程中,设置了默认语言为英语(en)并启用了调试模式(debug: true),以便在开发时查看语言切换的相关信息。此外,backend 配置项指定了翻译资源的加载路径为 /locales/{{lng}}/{{ns}}.json,其中 {{lng}}{{ns}} 会根据当前语言和命名空间动态替换。最后,interpolation.escapeValue: false 确保插值中的特殊字符不会被转义,从而避免出现渲染错误。

这个时候我们还需要创建一个 Provider,如下代码所示:

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>;
}

在这个 Provider 中我们要引入我们刚才编写的文件并给这个 Provider 提供值。

我们还可以再创建一个切换语言的按钮,来实现不同语言的切换:

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"} // Use resolvedLanguage for reliable check after init
        className="px-3 py-1 border rounded disabled:opacity-50"
      >
        English
      </button>
      <button
        onClick={() => changeLanguage("zh")}
        disabled={i18n.resolvedLanguage === "zh"} // Use resolvedLanguage
        className="px-3 py-1 border rounded disabled:opacity-50"
      >
        中文
      </button>
    </div>
  );
}

这段代码定义了一个 LanguageSwitcher 组件,它通过 useTranslation 钩子获取 i18n 实例。changeLanguage 函数用于切换当前语言,当传入不同的语言代码(lng)时,调用 i18n.changeLanguage 方法更新应用的语言设置。这使得用户可以动态切换界面语言。

接下来我们可以直接在我们的页面上使用了,这个时候我们还需要再我们的 layout 页面上全局包裹一下:

tsx 复制代码
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import I18nProvider from "@/components/I18nProvider";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <I18nProvider>{children}</I18nProvider>
      </body>
    </html>
  );
}

然后再我们的页面上直接使用:

tsx 复制代码
"use client";

import { useTranslation } from "react-i18next";
import LanguageSwitcher from "@/components/LanguageSwitcher";

export default function Home() {
  const { t } = useTranslation("common");

  return (
    <div className="grid grid-rows-[auto_1fr_auto] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <div className="flex items-center gap-4 justify-self-start self-center">
        <h1 className="text-2xl font-bold">{t("welcome")}</h1>
        <LanguageSwitcher />
      </div>
    </div>
  );
}

最终效果如下图所示:

我们点击 English 按钮之后会切换语言:

这样我们就在 React 里面实现了国际化的功能啦。

总结

国际化(i18n)是指设计和开发应用程序的方式,使其能够轻松适应多种语言、地区和文化需求,而无需进行大量的重新开发。通过国际化,应用程序可以支持文本翻译、日期和时间格式、货币符号等多种本地化需求。它为本地化(l10n)打下基础,本地化则是将应用具体翻译和调整为不同市场的语言和文化。国际化确保产品能够覆盖全球用户,提供一致且符合当地习惯的使用体验。

相关推荐
GISer_Jing2 小时前
前端面试通关:Cesium+Three+React优化+TypeScript实战+ECharts性能方案
前端·react.js·面试
落霞的思绪3 小时前
CSS复习
前端·css
咖啡の猫5 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲7 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5818 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路8 小时前
GeoTools 读取影像元数据
前端
ssshooter9 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友9 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry9 小时前
Jetpack Compose 中的状态
前端
dae bal10 小时前
关于RSA和AES加密
前端·vue.js