翻译 JSX
如何对 JSX 组件进行国际化
概述
本指南将带您了解如何使用 <T>
组件 对 JSX 内容进行国际化。
在本指南结束时,您将了解如何正确使用 <T>
组件的语法以及需要避免的问题。
我们将涵盖以下内容:
如何使用 <T>
组件
其他选项
何时使用 <T>
组件
示例
生产环境注意事项
常见陷阱
如果您想了解如何使用 Variable Components 或 Branching Components,请参考各自的指南。
如何使用 <T>
组件
假设你有一些 HTML 内容需要翻译。
function Greeting() {
return <p>Hello, world!</p>;
}
你只需要将内容包裹在 <T>
组件中即可。
import { T } from 'gt-react';
function Greeting() {
return <T><p>Hello, world!</p></T>;
}
根据用户当前选择的语言,这将渲染相应的翻译内容。
更多关于如何让用户切换语言的信息,请参见切换语言。
其他选项
上下文
在某些情况下,你可能希望为翻译提供额外的上下文信息。
这可以通过向 <T>
组件传递一个 context
属性来实现。
<T context="toast, as in a pop-up notification">
Click on the toast to dismiss it.
</T>
当某些单词根据上下文可能有多重含义时,这非常有用。 例如,“toast”既可以指食物,也可以指弹出通知。
context 属性有助于 AI 理解翻译的意图。
id
你也可以向 <T>
组件传递一个 id
属性。
这对于调试很有帮助,并且可以让编辑翻译变得更容易。
<T id="toast">
Click on the toast to dismiss it.
</T>
何时使用 <T>
组件
虽然 <T>
组件非常灵活,但并不总是最佳解决方案。
当你有任何静态 HTML 或 JSX 内容时,应始终尝试使用 <T>
组件。
何时不应使用 <T>
组件
不要在存在任何不安全的动态内容时使用 <T>
组件。
这里的动态内容指的是任何在运行时可能发生变化的内容。
如果你正在使用 Variable Components 或 Branching Components,此规则不适用。
注意:
Variable components 是一种特殊情况,内容虽然是动态的,但已经被包装并消毒,因此可以安全地使用 <T>
组件。
被 variable components 包裹的内容不会被 <T>
组件直接翻译。
以下示例展示了 <T>
组件的无效用法:
<T>
<p>Your username is {username}</p>
</T>
<T>
<p>Current date: {new Date().toLocaleDateString()}</p>
</T>
<T>
<p>Logical Expressions: {username === 'admin' ? 'Yes' : 'No'}</p>
</T>
<T>
<p>Conditional Rendering: {isAdmin ? 'Yes' : 'No'}</p>
</T>
在上述示例中,可以通过 variable components 和 branching components 安全地实现国际化。
const chatMessage = getChatMessageFromServer();
<T>
<p>{chatMessage}</p>
</T>
在此示例中,内容是完全动态的,因此应在服务器端进行翻译后再传递给客户端。
有关如何通过我们的 API 动态翻译内容的更多信息,请参阅 core 库。
示例
以下是如何使用 <T>
组件的一些示例。这些都是正确的用法。
- HTML 内容
<T>
<p>Hello, world!</p>
</T>
<p>Hello, world!</p>
- 简单 JSX 内容
<T>
<Button>Click me!</Button>
</T>
<Button>Click me!</Button>
- 复杂 JSX 内容
<T>
<Tooltip>
<TooltipTrigger>
<div className="flex items-center gap-2 rounded-full bg-destructive px-3 py-1.5 text-sm text-destructive-foreground">
<AlertCircle className="h-4 w-4" />
<span>Free Usage</span>
</div>
</TooltipTrigger>
<TooltipContent>
<p>
You are nearing your free monthly limit. Please
upgrade your plan to avoid any disruptions to your
service.
</p>
</TooltipContent>
</Tooltip>
</T>
<Tooltip>
<TooltipTrigger>
<div className="flex items-center gap-2 rounded-full bg-destructive px-3 py-1.5 text-sm text-destructive-foreground">
<AlertCircle className="h-4 w-4" />
<span>Free Usage</span>
</div>
</TooltipTrigger>
<TooltipContent>
<p>
You are nearing your free monthly limit. Please
upgrade your plan to avoid any disruptions to your
service.
</p>
</TooltipContent>
</Tooltip>
<T>
组件可以在同一个组件中处理任何嵌套内容。
生产环境注意事项
部署到生产环境
在部署到生产环境之前,请确保运行 translate 命令,以便所有翻译内容在运行时都可用。 我们建议将其添加到您的 CD 流水线或作为构建脚本的一部分。
{
"scripts": {
"build": "npx gtx-cli translate && <YOUR_BUILD_COMMAND>",
}
}
如需更详细的应用部署指南,请参阅 Deployment 教程。 有关该命令的更多信息,请参阅 CLI Tool 参考指南。
行为:开发环境与生产环境
在开发环境中,<T>
组件会按需翻译内容。
这意味着当组件被渲染时,会立即执行翻译操作。
该库这样设计是为了方便多语言开发。
要启用此行为,只需在环境中添加 Dev API 密钥。
在生产环境中,<T>
组件使用的所有翻译内容都会在构建时完成。
这意味着您必须在部署应用之前运行翻译命令。
提示: 如果您想在开发环境中模拟生产环境的行为,只需在开发构建中使用生产 API 密钥即可。
隐私问题
除少数例外,所有包裹在 <T>
组件中的内容都会被发送到 General Translation API 进行翻译。
对于渲染敏感数据(如用户名、账号等),这可能并不理想。
为避免此问题,请使用 Variable Components 来处理私密信息。 这样可以确保不会将任何敏感数据发送到 General Translation API 进行翻译。 任何包裹在变量组件中的内容的本地化都将在本地完成。
常见陷阱
仅限直接子元素
<T>
组件只会翻译直接作为子元素传递的文本。
这意味着,如果你在一个组件内部有内容,但这些内容没有直接传递给 <T>
,它们将不会被翻译。
让我们用一个例子来说明:
function UntranslatedContent() {
return (
<p>This content is not translated</p>
);
}
export default function DisplayGreetings() {
return (
<T>
<h1>Hello, this text will be translated</h1>
<UntranslatedContent />
</T>
);
}
在这个例子中,<UntranslatedContent>
内部的内容不会被翻译。
只有直接在 <T>
内部的内容会被翻译,比如 <h1>
标签及其子元素。
注意: 一个简单的经验法则是,任何字面上位于文件中两个 <T>
标签之间的内容都会被翻译。
你始终可以再添加一个 <T>
来翻译未被翻译的内容,尽管不推荐嵌套 <T>
组件。
如何修复?
直接将文本包裹在 <T>
组件中,如下所示:
function TranslatedContent() {
return (
<T>
<p>This content <b>IS</b> translated</p>
</T>
);
}
export default function DisplayGreetings() {
return (
<>
<T>
<h1>Hello, this text will be translated</h1>
</T>
<TranslatedContent />
</>
);
}
嵌套 <T>
组件
不允许嵌套 <T>
组件。
由于 React 的渲染机制,这样做可能会导致意外行为和性能问题。
下面是不要这样做的例子:
function SomeComponent() {
return (
<T>
Hello, friend!
</T>
);
}
export default function NestedTranslation() {
return (
<T>
<T> {/* 不要这样做! */}
Hello, world!
</T>
<SomeComponent /> {/* 这也算嵌套。不要这样做! */}
</T>
);
}
这里的解决方法是移除最外层的 <T>
组件。
翻译动态内容
如果你尝试用 <T>
组件包裹动态内容,CLI 工具会报错。
例如,下面的写法会报错:
const username = 'John Doe';
<T>
<p>Your username is {username}</p>
</T>
要解决这个问题,请尝试使用 Variable Components 或 Branching Components 来包裹动态内容。
摘要
<T>
组件用于对任意 JSX 内容进行国际化。<T>
组件不应在没有使用变量组件或分支组件的情况下用于动态内容。- 在开发环境中,
<T>
组件会按需翻译内容。 - 在生产环境中,
<T>
组件使用的所有翻译都会在构建时完成。
后续步骤
这份指南怎么样?