# General Translation React SDKs (gt-react, gt-next, gt-react-native): React SPA 快速入门
URL: https://generaltranslation.com/zh/docs/react/react-spa-quickstart.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: 为单页 React 应用添加多语言支持。

阅读完本指南后，你的单页 React 应用将能够以多种语言显示内容，并提供一个可供用户切换语言的语言切换器。

在单页应用中，`gt-react` 完全在浏览器中运行——你只需在启动时使用 [`initializeGTSPA()`](/docs/react/reference/config#initialize-spa) 初始化一次，无需 provider 组件。

**前提条件：**

* 一个客户端渲染的 React 应用 (Vite、webpack 或类似工具)
* Node.js 18+

你的构建系统可能需要更高版本的 Node.js。例如，Vite 8 需要 `^20.19.0 || >=22.12.0`。

<Callout type="info">
  &#42;&#42;提示：&#42;&#42;运行 `npx gt@latest`，通过 [设置向导](/docs/cli/quickstart) 配置 Vite 启动引导和翻译加载。本指南介绍手动设置。
</Callout>

<Callout type="info">
  &#42;&#42;注意：&#42;&#42;如果你的应用在服务器端渲染，请改为参考 [React 快速入门](/docs/react/react-quickstart)。
</Callout>

## 选择构建工具 [#bundlers]

以下步骤以 Vite 为例。若使用其他构建系统，请参阅相应的配置指南，了解入口文件、引导和翻译加载器的设置：

<Cards>
  <Card title="Vite" href="/docs/react/guides/spa/configuring-vite-spa">
    配置 Vite HTML 入口和翻译加载。
  </Card>

  <Card title="webpack" href="/docs/react/guides/spa/configuring-webpack-spa">
    配置 webpack 入口和翻译上下文。
  </Card>

  <Card title="esbuild" href="/docs/react/guides/spa/configuring-esbuild-spa">
    配置 esbuild 入口文件和输出目标后备内容。
  </Card>

  <Card title="Rollup" href="/docs/react/guides/spa/configuring-rollup-spa">
    配置 Rollup 输入和可静态分析的区域设置映射。
  </Card>

  <Card title="Rolldown" href="/docs/react/guides/spa/configuring-rolldown-spa">
    配置 Rolldown 输入和可静态分析的区域设置映射。
  </Card>

  <Card title="Bazel" href="/docs/react/guides/spa/configuring-bazel-spa">
    将引导、配置、package 和翻译声明为 Bazel 输入。
  </Card>
</Cards>

完成设置后，请参阅 [React SPA 国际化](/docs/react/guides/spa/internationalizing-react-spa)，
了解 JSX、字符串、区域设置选择和验证方面的 SPA 专用指南。

## 快速入门 [#quickstart]

### 1. 安装软件包

`gt-react` 是为你的应用提供翻译功能的库。`gt` 是用于准备翻译内容的 CLI 工具。

<Tabs items={['npm', 'yarn', 'bun', 'pnpm']}>
  <Tab value="npm">
    ```bash
    npm i gt-react
    npm i -D gt
    ```
  </Tab>

  <Tab value="yarn">
    ```bash
    yarn add gt-react
    yarn add --dev gt
    ```
  </Tab>

  <Tab value="bun">
    ```bash
    bun add gt-react
    bun add --dev gt
    ```
  </Tab>

  <Tab value="pnpm">
    ```bash
    pnpm add gt-react
    pnpm add --save-dev gt
    ```
  </Tab>
</Tabs>

### 2. 创建翻译配置文件

在项目根目录中创建一个 **`gt.config.json`** 文件。这样可以告诉该库你支持哪些语言：

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "fr", "ja"],
  "files": {
    "gt": {
      "output": "src/_gt/[locale].json"
    }
  }
}
```

* **`defaultLocale`** — 你的应用使用的语言 (即源语言) 。
* **`locales`** — 你要翻译到的语言。可从[支持的区域设置列表](/docs/platform/dashboard/reference/supported-locales)中任选。
* **`files`** — 指定 CLI 将翻译文件保存到哪里。`output` 路径应与 [`loadTranslations`](/docs/react/reference/functions/load-translations) 函数中的导入路径一致 (第 3 步) 。

CLI 默认扫描 `src`、`app`、`pages` 和 `components` 目录下的 JavaScript 和 TypeScript 文件。如果你的源代码位于其他位置，请设置 [`src`](/docs/cli/reference/config#src)。

<Callout type="info">
  &#42;&#42;注意：&#42;&#42;Vite 之类的构建工具会将翻译文件作为模块导入，因此翻译文件应放在 `src/` 目录下。
</Callout>

### 3. 创建翻译加载器

在 SPA 中，`gt-react` 需要一个函数在浏览器运行时加载翻译文件。创建一个 [`loadTranslations`](/docs/react/reference/functions/load-translations) 文件：

```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
  try {
    const translations = await import(`./_gt/${locale}.json`);
    return translations.default;
  } catch (error) {
    console.warn(`No translations found for ${locale}`);
    return {};
  }
}
```

此函数会从你的 `src/_gt/` 目录中加载 JSON 翻译文件。运行 [`npx gt translate`](/docs/cli/reference/commands/translate) 时，CLI 会生成这些文件。

<Callout type="info">
  **Rollup：** 标准 Rollup 无法分析上方完全动态的导入。请改用[静态区域设置加载器映射](/docs/react/guides/developing-spa-translations#setup)。
</Callout>

<Accordions>
  <Accordion title="将 Create React App 翻译保留在 public/ 中？">
    Create React App 可以使用上方的源目录加载器。如果你希望将生成翻译保留在 `public/` 中，请将 CLI 输出更改为 `public/_gt/[locale].json`：

    ```json title="gt.config.json"
    {
      "defaultLocale": "en",
      "locales": ["es", "fr", "ja"],
      "files": {
        "gt": {
          "output": "public/_gt/[locale].json"
        }
      }
    }
    ```

    使用 `PUBLIC_URL` 通过 HTTP 加载文件：

    ```ts title="src/loadTranslations.ts"
    export default async function loadTranslations(locale: string) {
      try {
        const response = await fetch(
          `${process.env.PUBLIC_URL}/_gt/${locale}.json`
        );
        if (!response.ok) throw new Error('Translation file not found');
        return await response.json();
      } catch {
        console.warn(`No translations found for ${locale}`);
        return {};
      }
    }
    ```
  </Accordion>
</Accordions>

### 4. 初始化库

在启动时、应用渲染前调用一次 **[`initializeGTSPA`](/docs/react/reference/config#initialize-spa)**。它会接收你的配置和翻译加载器，确定用户的区域设置，并加载对应的翻译内容。

最稳妥的做法是使用一个小型入口模块，先初始化 GT，再加载应用的其余部分。这样你就能在模块级别翻译内容。

```ts title="src/index.ts"
import { initializeGTSPA } from 'gt-react';
import gtConfig from '../gt.config.json';
import loadTranslations from './loadTranslations';

await initializeGTSPA({
  ...gtConfig,
  loadTranslations,
});

await import('./main'); // 仅在 GT 就绪后才渲染应用
```

<Accordions>
  <Accordion title="使用 CommonJS？">
    CommonJS 不支持顶层 await。请将初始化放在一个异步启动函数中，并在之后动态导入应用。这样可以保留模块级 [`t()`](/docs/react/reference/functions/t-function) 调用所需的异步边界。

    ```js title="src/index.js"
    const { initializeGTSPA } = require('gt-react');
    const gtConfig = require('../gt.config.json');

    async function loadTranslations(locale) {
      try {
        return require(`./_gt/${locale}.json`);
      } catch (error) {
        console.warn(`No translations found for ${locale}`);
        return {};
      }
    }

    async function start() {
      await initializeGTSPA({
        ...gtConfig,
        loadTranslations,
      });

      await import('./main');
    }

    start().catch(console.error);
    ```

    <Callout type="warn">
      **警告：** 不要在初始化之前 require `main`。这样会在翻译准备就绪之前执行模块级的 [`t()`](/docs/react/reference/functions/t-function) 调用。
    </Callout>
  </Accordion>
</Accordions>

```tsx title="src/main.tsx"
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>
);
```

在 Vite 中，更新 `index.html` 中的模块 script 标签，使其指向新的入口：将其 `src` 从 `/src/main.tsx` 改为 `/src/index.ts`。

```html title="index.html"
<!-- <script type="module" src="/src/main.tsx"></script> -->
<script type="module" src="/src/index.ts"></script>
```

[`initializeGTSPA`](/docs/react/reference/config#initialize-spa) 只会在启动时运行一次——在应用的整个生命周期内，配置都是不可变的。它完成后，你就可以在任何模块中获取翻译。**你不需要用 provider 包裹应用。**

<Accordions>
  <Accordion title="使用 Create React App？">
    Create React App 会阻止从 `src/` 外部导入，并且不支持顶层 `await`。请保留根目录的 `gt.config.json` 供 CLI 使用，将现有的 `src/index.tsx` 入口重命名为 `src/main.tsx`，然后创建以下新入口：

    ```ts title="src/index.ts"
    import { initializeGTSPA } from 'gt-react';
    import loadTranslations from './loadTranslations';

    async function start() {
      await initializeGTSPA({
        defaultLocale: 'en',
        locales: ['es', 'fr', 'ja'],
        loadTranslations,
      });

      await import('./main');
    }

    start().catch(console.error);
    ```

    每次添加或移除语言时，都要让这些区域设置值与根配置保持同步。保持 `public/index.html` 不变；Create React App 已会加载 `src/index`。
  </Accordion>
</Accordions>

<Callout type="info">
  **提示：** 请按照[使用 SPA translations 进行开发](/docs/react/guides/developing-spa-translations)添加 compiler 和开发凭据。
</Callout>

### 5. 标记要翻译的内容

现在，将任何需要翻译的文本用 **[`<T>`](/docs/react/reference/components/t)** 组件包裹起来。[`<T>`](/docs/react/reference/components/t) 表示 &quot;translate&quot;：

```tsx title="src/components/Welcome.tsx"
import { T } from 'gt-react';

export default function Welcome() {
  return (
    <main>
      <T>
        <h1>Welcome to my app</h1>
        <p>This content will be translated automatically.</p>
      </T>
    </main>
  );
}
```

你可以在 [`<T>`](/docs/react/reference/components/t) 中包裹任意多或任意少的 JSX。里面的所有内容——文本、嵌套元素，甚至格式——都会作为一个整体被翻译。

对于 React 组件外的字符串，请使用 **[`t()`](/docs/react/reference/functions/t-function)**。它可以在模块级别使用，因为 [`initializeGTSPA()`](/docs/react/reference/config#initialize-spa) 会在应用其余部分加载前先加载翻译：

```ts title="src/navigation.ts"
import { t } from 'gt-react';

export const navigation = [
  { label: t('Home'), href: '/' },
  { label: t('About'), href: '/about' },
];
```

### 6. 添加语言切换器

添加一个 **[`<LocaleSelector>`](/docs/react/reference/components/locale-selector)**，让用户可以切换语言：

```tsx title="src/components/Welcome.tsx"
import { T, LocaleSelector } from 'gt-react';

export default function Welcome() {
  return (
    <main>
      <LocaleSelector />
      <T>
        <h1>Welcome to my app</h1>
        <p>This content will be translated automatically.</p>
      </T>
    </main>
  );
}
```

[`LocaleSelector`](/docs/react/reference/components/locale-selector) 会渲染一个下拉菜单，其中会显示来自你的 `gt.config.json` 的语言。

当用户选择一种语言时，`gt-react` 会将该选择保存到 `generaltranslation.locale` cookie 中，并重新加载页面——随后 [`initializeGTSPA`](/docs/react/reference/config#initialize-spa) 会再次运行，在应用渲染之前加载新区域设置的翻译内容。

### 7. 身份验证并翻译

开始翻译前，请先通过 General Translation 进行身份验证：

```bash
npx gt auth
```

按照提示创建账户或登录。系统提示选择密钥类型时，请选择生产环境密钥。该命令会生成 API Key 和 project ID，然后将它们添加到项目根目录下的 `.env.local`：

```bash title=".env.local"
GT_PROJECT_ID="your-project-id"
GT_API_KEY="gtx-api-your-production-key"
```

<Callout type="warn">
  &#42;&#42;警告：&#42;&#42;不要提交 `.env.local`，也不要在浏览器端代码中暴露 `GT_API_KEY`。
</Callout>

然后运行 translate 命令，为每个已配置的区域设置生成翻译文件：

```bash
npx gt translate
```

CLI 会扫描你的应用、翻译其中的内容，并将结果写入 `gt.config.json` 中指定的输出路径。每当 source 内容发生变化时，都可以再次运行它。

### 8. 运行并验证

在应用中渲染示例组件：

```tsx title="src/App.tsx"
import Welcome from './components/Welcome';

export default function App() {
  return <Welcome />;
}
```

启动应用的开发服务器 (例如在 Vite 中运行 `npm run dev`) ，打开本地 URL，然后选择 `es`、`fr` 或 `ja`。确认页面会重新加载，且标题显示为所选语言的译文。

## 故障排查 [#troubleshooting]

<Accordions>
  <Accordion title="使用下拉菜单时语言没有切换">
    确认浏览器已启用 Cookie、所选区域设置已列在 `gt.config.json` 中，且 [`initializeGTSPA`](/docs/react/reference/config#initialize-spa) 会在应用程序入口模块加载前完成。
  </Accordion>

  <Accordion title="某些翻译不够准确">
    有歧义的文本可能会导致翻译不准确。例如，“apple” 既可能指水果，也可能指公司。添加 `$context` prop 来提供上下文：

    ```jsx
    <T $context="the technology company">Apple</T>
    ```

    [`<T>`](/docs/react/reference/components/t) 和 [`useGT()`](/docs/react/reference/hooks/use-gt) 都支持 `$context` 选项。
  </Accordion>
</Accordions>

## Next steps

- /docs/react/guides/developing-spa-translations
- /docs/react/guides/translating-jsx
- /docs/react/guides/managing-locales
- /docs/react/guides/storing-translations

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
