# General Translation React SDKs (gt-react, gt-next, gt-react-native): Next.js Pages Router 快速入门
URL: https://generaltranslation.com/zh/docs/react/nextjs-pages-router-quickstart.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: 使用 General Translation，在 10 分钟内为 Next.js Pages Router 应用添加多语言支持。

完成本指南后，您的 Next.js Pages Router 应用将能够以多种语言显示内容，并提供一个可供用户交互的语言切换器。

在 Pages Router 中，`gt-next` 通过 `getServerSideProps` 运行：服务器会在每次请求时解析用户的区域设置，加载翻译快照，并将两者传递给 `_app.tsx` 中的 [`<GTProvider>`](/docs/react/reference/components/gt-provider)，这样首次渲染时显示的内容就已经是翻译后的。

`gt-next/server` 入口仅适用于 App Router，不适用于 Pages Router。

**前提条件：**

* 一个使用 **Pages Router** 的 Next.js 应用 (Next.js 13.0.0 或更高版本，不包括 15.2.1 和 15.2.2) 
* Node.js 18+

<Callout type="info">
  **注意：** 如果您使用的是 App Router，请改为参考 [Next.js App Router 快速入门](/docs/react/nextjs-quickstart)。它使用服务器组件，无需配置 `getServerSideProps`。
</Callout>

## 快速入门 [#quickstart]

### 1. 安装依赖包

`gt-next` 是为你的应用提供翻译能力的库。`gt` 是用于为生产环境准备翻译内容的 CLI 工具。

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

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

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

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

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

在项目根目录下创建一个 **`gt.config.json`** 文件，用于告知该库你支持哪些语言：

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

* **`defaultLocale`** — 你的应用所使用的语言 (即源语言) 。
* **`locales`** — 应用中可用的所有区域设置。由于 Next.js 的国际化路由需要它，因此请包含 `defaultLocale`，然后添加你想要翻译成的语言。可从[受支持的区域设置列表](/docs/platform/dashboard/reference/supported-locales)中任选。
* **`files.gt.output`** — CLI 保存翻译文件的位置。`[locale]` 会替换为各个语言代码 (例如 `public/_gt/es.json`) 。

将 `public/_gt/` 添加到你的 **`.gitignore`** 中 —— 这些文件是自动生成的，不是手动编写的：

```txt title=".gitignore"
public/_gt/
```

### 3. 配置 Next.js 国际化路由

Pages Router 使用 [Next.js 国际化路由](https://nextjs.org/docs/pages/guides/internationalization) 实现带区域设置前缀的 URL 和请求区域设置检测。将区域设置导入 `next.config.ts`，然后使用 `withGTConfig` 包装配置：

```ts title="next.config.ts"
import type { NextConfig } from 'next';
import { withGTConfig } from 'gt-next/config';
import gtConfig from './gt.config.json';

const nextConfig: NextConfig = {
  i18n: {
    locales: gtConfig.locales,
    defaultLocale: gtConfig.defaultLocale,
  },
};

export default withGTConfig(nextConfig);
```

Next.js 将默认区域设置保留在 `/`，并为其他区域设置添加前缀，例如 `/es` 和 `/fr`。您无需使用 `gt-next` 中间件或 `pages/[locale]` 路由段。有关检测和迁移的详细信息，请参阅 [Pages Router 区域设置路由](/docs/react/nextjs/pages-router-middleware)。

### 4. 为本地翻译添加 load function

在项目根目录 (或 `src/` 目录) 中创建一个 **[`loadTranslations`](/docs/react/reference/functions/load-translations)** 文件。这会告诉 `gt-next` 如何加载由 CLI 生成的翻译文件：

```ts title="loadTranslations.ts"
export default async function loadTranslations(locale: string) {
  try {
    const translations = await import(`./public/_gt/${locale}.json`);
    return translations.default;
  } catch {
    return {};
  }
}
```

<Callout type="info">
  &#42;&#42;注意：&#42;&#42;这些翻译文件要等到你使用 [`npx gt generate`](/docs/cli/reference/commands/generate) 创建后才会存在 (无需 API 密钥) ，或者使用 [`npx gt translate`](/docs/cli/reference/commands/translate) 创建 (需要凭据) 。在此之前，打包工具会对缺失的 `public/_gt` 目录发出警告，而上面的 `try`/`catch` 会返回 `{}`，因此应用仍可在内容未翻译的情况下运行。
</Callout>

`withGTConfig` 会自动检测项目根目录或 `src/` 目录中的 `loadTranslations.[js|ts]` 文件，无需额外配置。

<Callout type="info">
  &#42;&#42;注意：&#42;&#42;本地翻译会随应用一同打包，因此可即时加载，无需依赖外部服务。有关详情及其中的权衡取舍，请参阅[存储翻译](/docs/react/guides/storing-translations)。
</Callout>

### 5. 在页面中包装 getServerSideProps

用 **`withGTServerSideProps`** 包装每个页面的 `getServerSideProps`。每次收到请求时，它都会读取 Next.js 解析后写入 `context.locale` 的区域设置，加载该区域设置对应的翻译快照，并将两者一并注入页面 属性 中：

```tsx title="pages/index.tsx"
import type { GetServerSideProps } from 'next';
import { withGTServerSideProps } from 'gt-next';

export const getServerSideProps: GetServerSideProps = withGTServerSideProps(
  async (context) => {
    return {
      props: {
        // 你自己的属性
      },
    };
  }
);
```

如果某个页面自身不需要服务器端属性，就直接在不传任何参数的情况下调用它：

```tsx title="pages/about.tsx"
import { withGTServerSideProps } from 'gt-next';

export const getServerSideProps = withGTServerSideProps();
```

`withGTServerSideProps` 会将 `locale` 和 `translations` 添加到你的属性中 (以及一个内部使用的 `enableI18n` 标志) 。如果内部函数返回 `redirect` 或 `notFound`，它会直接原样返回结果，而不会加载翻译内容。

### 6. 将 GTProvider 添加到应用中

**[`GTProvider`](/docs/react/reference/components/gt-provider)** 组件可让整个应用访问翻译内容。在 `_app.tsx` 中，从 `pageProps` 中取出注入的属性，并将其传递给 **`GTProvider`**。**`WithGTServerSideProps`** 类型描述了这些注入属性的结构：

```tsx title="pages/_app.tsx"
import type { AppProps } from 'next/app';
import Router from 'next/router';
import { GTProvider, type WithGTServerSideProps } from 'gt-next';

export default function App({
  Component,
  pageProps,
}: AppProps<WithGTServerSideProps>) {
  const { locale, translations } = pageProps;

  return (
    <GTProvider
      locale={locale}
      translations={translations}
      _reload={({ locale: nextLocale }) => {
        void Router.push(Router.pathname, Router.asPath, {
          locale: nextLocale,
        });
      }}
    >
      <Component {...pageProps} />
    </GTProvider>
  );
}
```

由于区域设置和翻译会随服务器端响应一同返回，因此首次渲染时内容就已经是用户所用的语言——无需客户端加载状态。`_reload` 回调函数会将区域设置变更传递给 Next.js 路由器，使其加载所选区域设置的页面属性。

### 7. 标记需要翻译的内容

现在，用 **[`<T>`](/docs/react/reference/components/t)** 组件包裹你想翻译的任何文本。[`<T>`](/docs/react/reference/components/t) 表示“translate”：

```tsx title="pages/index.tsx"
import { T } from 'gt-next';

export default function Home() {
  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。里面的所有内容——文本、嵌套元素，甚至格式——都会作为一个整体进行翻译。

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

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

```tsx title="pages/index.tsx"
import { T, LocaleSelector } from 'gt-next';

export default function Home() {
  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`。当用户选择一种语言后，`_app.tsx` 中的回调函数会跳转到本地化 URL，Next.js 会将该选择保存到 `NEXT_LOCALE` cookie 中。随后，服务器端会渲染所选的区域设置。

### 9. 设置环境变量 (可选)

要在开发环境中查看翻译效果，你需要 General Translation 提供的 API 密钥。它们可启用**按需翻译**——这样你在开发过程中，应用就能实时翻译内容。

创建一个 **`.env.local`** 文件：

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

前往 [dash.generaltranslation.com](https://dash.generaltranslation.com/en-US/signin) 免费获取密钥，或运行：

```bash
npx gt auth
```

<Callout type="warn">
  **警告：** 在开发环境中，请使用以 `gtx-dev-` 开头的密钥。生产环境密钥 (`gtx-api-`) 仅限用于 CI/CD。

  切勿将 `GT_API_KEY` 暴露给浏览器，也不要将其提交到源代码版本控制系统中。
</Callout>

### 10. 查看效果

启动开发服务器：

<Tabs items={['npm', 'yarn', 'bun', 'pnpm']}>
  <Tab value="npm">
    ```bash
    npm run dev
    ```
  </Tab>

  <Tab value="yarn">
    ```bash
    yarn dev
    ```
  </Tab>

  <Tab value="bun">
    ```bash
    bun dev
    ```
  </Tab>

  <Tab value="pnpm">
    ```bash
    pnpm dev
    ```
  </Tab>
</Tabs>

打开 [http://localhost:3000](http://localhost:3000)，然后使用语言下拉菜单切换语言。你应该能看到内容已被翻译。

<Callout type="info">
  **注意：** 在开发环境中，翻译是按需进行的，因此第一次切换到新语言时，你可能会短暂看到加载状态。在生产环境中，翻译会预先生成，并可立即加载。
</Callout>

### 11. 翻译字符串 (不仅仅是 JSX)

对于普通字符串 (如 `placeholder` 属性、`aria-label` 值或 `alt` 文本) ，请使用 **[`useGT`](/docs/react/reference/hooks/use-gt)** 钩子：

```tsx title="pages/contact.tsx"
import { useGT } from 'gt-next';

export default function ContactPage() {
  const gt = useGT();

  return (
    <form>
      <input
        placeholder={gt('Enter your email')}
        aria-label={gt('Email input field')}
      />
      <button type="submit">{gt('Send')}</button>
    </form>
  );
}
```

### 12. 部署到生产环境

在生产环境中，翻译会在构建阶段预先生成 (不会发起实时 API 调用) 。将 translate 命令添加到构建脚本中：

```json title="package.json"
{
  "scripts": {
    "build": "npx gt translate && next build"
  }
}
```

在你的托管平台 (Vercel、Netlify 等) 中设置 **生产** 环境变量：

```bash
GT_PROJECT_ID=your-project-id
GT_API_KEY=gtx-api-your-production-key
```

<Callout type="warn">
  &#42;&#42;警告：&#42;&#42;Production keys 以 `gtx-api-` 开头 (不是 `gtx-dev-`) 。请前往 [dash.generaltranslation.com](https://dash.generaltranslation.com) 获取。切勿添加 `NEXT_PUBLIC_` 前缀。
</Callout>

就是这样——你的应用现在已经支持多语言了。🎉

## 故障排查 [#troubleshooting]

<Accordions>
  <Accordion title="每个页面都需要使用 withGTServerSideProps 吗？">
    是的——[`<GTProvider>`](/docs/react/reference/components/gt-provider) 需要 `locale` 和 `translations` 属性，而这两个属性只会出现在 `getServerSideProps` 经过包装的页面上。对于不自行获取数据的页面，请导出无参数形式：

    ```tsx
    export const getServerSideProps = withGTServerSideProps();
    ```
  </Accordion>

  <Accordion title="可以改用 getStaticProps 吗？">
    可以。用 `withGTStaticProps` 包装页面，并继续在 `_app.tsx` 中将生成的属性传给 [`GTProvider`](/docs/react/reference/components/gt-provider)。完整设置请参见 [Pages Router 静态站点生成指南](/docs/react/nextjs/pages-router-static-site-generation)。
  </Accordion>

  <Accordion title="使用下拉菜单时，语言没有切换">
    请确认 `_reload` 会如上所示，使用所选的 `locale` 选项调用 `Router.push`。选择后，URL 应使用区域设置前缀，且 `NEXT_LOCALE` cookie 应包含该区域设置。
  </Accordion>

  <Accordion title="开发环境中的翻译较慢">
    这是正常现象。在开发环境中，翻译是按需进行的 (你的内容会通过 API 实时翻译) 。**生产环境中不会有这种延迟**——所有翻译都会由 [`npx gt translate`](/docs/cli/reference/commands/translate) 预先生成。
  </Accordion>
</Accordions>

## Next steps

- /docs/react/guides/translating-jsx
- /docs/react/guides/translating-strings
- /docs/react/guides/managing-locales
- /docs/react/guides/formatting-variables

## Sitemap

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