翻译字符串
如何实现字符串的国际化
概述
本指南将引导您了解如何使用 useGT()
hook 和 getGT()
函数在您的 Next.js 应用中国际化字符串。
我们将涵盖以下内容:
何时使用 useGT()
hook
如何使用 useGT()
hook
使用变量
示例
常见陷阱
在本指南中,当我们提到 useGT()
hook 时,我们也指的是 getGT()
函数。
两者之间的唯一区别是何时使用它们。
getGT()
函数是一个异步函数,返回一个 promised 函数,
而 useGT()
hook 直接返回函数。
在同步组件中使用 getGT()
函数,
在异步组件中使用 useGT()
hook。
import { useGT } from 'gt-next';
export function MyComponent() {
const translate = useGT();
const translatedString = translate('Hello, world!');
return <div>{translatedString}</div>;
}
import { getGT } from 'gt-next/server';
export async function MyComponent() {
const translate = await getGT();
const translatedString = translate('Hello, world!');
return <div>{translatedString}</div>;
}
何时使用 useGT()
钩子
useGT()
钩子是一个可以用于翻译字符串的 React 钩子。
在大多数情况下,你可以使用 <T>
组件。
然而,在某些不适合使用 JSX 的场景下,可以使用 useGT()
钩子。
以下是一些更适合使用 useGT()
钩子的情况:
- 在只接受字符串的属性中,例如
placeholder
或title
属性。 - 当字符串是更大对象的一部分时,例如:
const user = {
title: 'Mr.',
name: 'John',
description: 'John is a software engineer at General Translation',
}
在这里,只有 description
属性需要被翻译。
在可能的情况下,你应该使用 <T>
组件。
<T>
组件允许你翻译 JSX 内容,是推荐的字符串翻译方式。
如何使用 useGT()
hook
useGT()
hook 必须在 <GTProvider>
内部调用。
要翻译字符串,只需将字符串直接传递给 hook 返回的函数。
import { useGT } from 'gt-next';
export function MyComponent() {
const translate = useGT();
return <div>{translate('Hello, world!')}</div>;
}
与传统的 i18n 库不同,useGT()
hook 不需要您向函数传递 key
。
相反,字符串直接传递给函数。
这意味着您不需要使用字典!
如何使用 getGT()
函数
另一方面,由于 getGT()
函数是一个异步函数,
它可以在异步组件中使用,并且不需要在 <GTProvider>
内调用。
getGT()
的上下文由你的 next.config.ts
文件中的 withGTConfig
函数处理。
import { getGT } from 'gt-next/server';
export async function MyComponent() {
const translate = await getGT();
return <div>{translate('Hello, world!')}</div>;
}
使用变量
通常,您需要翻译包含变量的字符串。
例如,您可能需要翻译包含数值的字符串。
要添加变量,只需将变量作为占位符 {variable}
添加到字符串中,
并将对象作为第二个参数传递给钩子返回的函数。
const price = 100;
const translate = useGT();
translate('There are {count} items in the cart', { count: 10 });
{count}
占位符将被 count
变量的值替换。
这允许您在翻译中显示动态值。
有关 API 的更多信息,请参阅 API 参考。
gt-next
支持 ICU 消息格式,这也允许您格式化变量。
const price = 100;
const translate = useGT();
translate('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart', { count: 10 });
ICU 消息格式是格式化变量的强大方式。 有关更多信息,请参阅 ICU 消息格式文档。
示例
- 在组件中翻译字符串
import { useGT } from 'gt-next';
export default function MyComponent() {
const t = useGT();
return (
<div>
<h1>{t('Hello, world!')}</h1>
</div>
)
}
export default function MyComponent() {
return (
<div>
<h1>Hello, world!</h1>
</div>
)
}
- 翻译带变量的字符串
import { useGT } from 'gt-next';
export default function MyComponent() {
const t = useGT();
const count = 10;
return (
<div>
<h1>{t('There are {count} items in the cart', { count })}</h1>
</div>
)
}
export default function MyComponent() {
const count = 10;
return (
<div>
<h1>There are {count} items in the cart</h1>
</div>
)
}
- 翻译对象的部分内容
import { useGT } from 'gt-next';
export default function MyComponent() {
const t = useGT();
const users = [
{
name: 'John',
description: t('John is a software engineer at General Translation'),
},
{
name: 'Jane',
description: t('Jane is a software engineer at Google'),
},
]
return (
<div>
{users.map((user) => (
<div key={user.name}>
<h1>{user.name}</h1>
<p>{user.description}</p>
</div>
))}
</div>
)
}
export default function MyComponent() {
const users = [
{
name: 'John',
description: 'John is a software engineer at General Translation',
},
{
name: 'Jane',
description: 'Jane is a software engineer at Google',
},
]
return (
<div>
{users.map((user) => (
<div key={user.name}>
<h1>{user.name}</h1>
<p>{user.description}</p>
</div>
))}
</div>
)
}
- 翻译共享常量
// Custom function to get LLM data with translations
export function getLLMData(t: (content: string) => string) {
return [
{
name: 'GPT-4.1',
id: 'gpt-4.1',
description: t('GPT-4.1 is a large language model developed by OpenAI'),
},
{
name: 'Claude 3.7 Sonnet',
id: 'claude-3-7-sonnet',
description: t('Claude 3.7 Sonnet is a large language model developed by Anthropic'),
},
]
}
import { getLLMData } from './llms';
import { useGT } from 'gt-next';
export default function MyComponent() {
const t = useGT();
const llms = getLLMData(t);
return (
<div>
{llms.map((llm) => (
<div key={llm.id}>
<h1>{llm.name}</h1>
<p>{llm.description}</p>
</div>
))}
</div>
)
}
export const llms = [
{
name: 'GPT-4.1',
id: 'gpt-4.1',
description: 'GPT-4.1 is a large language model developed by OpenAI',
},
{
name: 'Claude 3.7 Sonnet',
id: 'claude-3-7-sonnet',
description: 'Claude 3.7 Sonnet is a large language model developed by Anthropic',
},
]
import { llms } from './llms';
export default function MyComponent() {
return (
<div>
{llms.map((llm) => (
<div key={llm.id}>
<h1>{llm.name}</h1>
<p>{llm.description}</p>
</div>
))}
</div>
)
}
在最后这个例子中,我们将 llms
数组转换为一个返回带有翻译数据的函数。
我们将 t
函数传递给返回数据的函数。
或者,你也可以将 llms
数组转换为自定义 hook。
但是,这不推荐,因为你需要非常小心地使用 useGT()
hook,
以免违反 React 的规则。
常见陷阱
翻译动态内容
所有字符串都必须在构建时已知。
这意味着你无法翻译在运行时生成或获取的动态内容。
这包括变量,即使它们是字符串。
export default function MyComponent() {
const [dynamicContent, setDynamicContent] = useState('Hello, world!');
const t = useGT();
return (
<div>
<h1>{t(dynamicContent)}</h1> {/* This will not work */}
</div>
)
}
如果你尝试用 useGT()
hook 翻译动态内容,CLI 工具会发出警告。
下一步
- 了解如何按需翻译 JSX 内容。
- 进一步了解
<T>
组件。 - 查看
useGT()
的 API 参考。
这份指南怎么样?