# General Translation React SDKs (gt-react, gt-next, gt-react-native): 设置 TanStack Start
URL: https://generaltranslation.com/zh/docs/react/tanstack-start/setup.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: 注册 General Translation 请求中间件，初始化 TanStack Start 应用，解析区域设置，并为 provider 提供水合数据。

`gt-tanstack-start` 使用全局请求中间件、模块级路由器初始化和 root 路由加载器。中间件会为服务器端代码创建请求级局部状态，而 root 加载器会使用区域设置和翻译为 [`<GTProvider>`](/docs/react/reference/components/gt-provider) 提供水合数据。

本页介绍 TanStack Start 特有的配置。要了解包括安装和 CLI 在内的完整流程，请参阅 [TanStack Start Quickstart](/docs/react/tanstack-start-quickstart)。

<Callout type="warn">
  **警告：** `gt-tanstack-start` 仍处于实验阶段，可能会有破坏性变更。
</Callout>

*注意：`gt-tanstack-start` 仅支持 ESM。请使用 `import` 语法，而不要使用 CommonJS 的 `require()`。*

*注意：此配置要求使用 `gt-tanstack-start` 11.1.5 或更高版本，以便在客户端构建中可从包的主入口解析 [`gtMiddleware`](/docs/react/tanstack-start/reference/functions/gt-middleware)。*

## 加载翻译 [#load-translations]

创建一个 [`loadTranslations`](/docs/react/reference/functions/load-translations) 函数，用于导入某个区域设置的翻译文件。将这些文件保存在 `src/` 目录下，以便 Vite 可以导入它们。

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

运行 [`npx gt translate`](/docs/cli/reference/commands/translate) 时，CLI 会生成这些文件。

## 注册请求中间件 [#middleware]

创建 `src/start.ts`，并将 [`gtMiddleware`](/docs/react/tanstack-start/reference/functions/gt-middleware) 注册为全局请求中间件。定义自定义的 start 实例时，请保留 TanStack Start 的跨站请求伪造 (CSRF) 中间件。

```ts title="src/start.ts"
import { createCsrfMiddleware, createStart } from '@tanstack/react-start';
import { gtMiddleware } from 'gt-tanstack-start';

const csrfMiddleware = createCsrfMiddleware({
  filter: ({ handlerType }) => handlerType === 'serverFn',
});

export const startInstance = createStart(() => ({
  requestMiddleware: [csrfMiddleware, gtMiddleware],
}));
```

该中间件会为每个请求解析一次区域设置、区域和国际化设置。它会将解析后的区域设置保存在 locale cookie 中，并在服务器上向[同构运行时函数](/docs/react/tanstack-start/using-server-functions)提供请求状态。

## 初始化并解析区域设置 [#initialize]

[`initializeGT`](/docs/react/reference/config#initialize)、[`getLocale`](/docs/react/tanstack-start/reference/functions/get-locale) 和 [`getTranslationsSnapshot`](/docs/react/reference/functions/get-translations-snapshot) 都从 `gt-tanstack-start` 导入：

* **[`initializeGT`](/docs/react/reference/config#initialize)** — 在 `src/router.tsx` 的模块作用域中调用一次。展开你的 `gt.config.json`，并传入 [`loadTranslations`](/docs/react/reference/functions/load-translations)。
* **[`getLocale`](/docs/react/tanstack-start/reference/functions/get-locale)** — 在服务器端返回活动中间件层级中的区域设置，在客户端则返回已初始化的浏览器条件存储中的区域设置。
* **[`getTranslationsSnapshot`](/docs/react/reference/functions/get-translations-snapshot)** — 以 [`<GTProvider>`](/docs/react/reference/components/gt-provider) 所需的格式加载某个区域设置的翻译，这样内容渲染时就不会出现加载闪烁。参见[参考文档](/docs/react/reference/functions/get-translations-snapshot)。

## 启用区域设置路由 [#locale-routing]

区域设置路由需要显式启用。启用前，请配置 TanStack Router，使其同时匹配不带前缀的默认区域设置 URL (例如 `/about`) 和带区域设置前缀的 URL (例如 `/es/about`) 。

你可以在基于文件或基于代码的路由中添加[可选的 `/{-$locale}` 段](https://tanstack.com/router/v1/docs/guide/internationalization-i18n#i18n-with-optional-path-parameters)，或使用 TanStack Router 的 [`rewrite` 选项](https://tanstack.com/router/v1/docs/guide/internationalization-i18n#url-localization-via-router-rewrite)，将带区域设置前缀的公共 URL 映射到现有路由树。例如，可选路由路径 `/{-$locale}/about` 可匹配 `/about`、`/es/about` 和 `/ja/about`。

路由器接受这两种 URL 形式后，在 `gt.config.json` 中将 `localeRouting` 设为 `true`：

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "ja"],
  "localeRouting": true
}
```

`gt-tanstack-start` 不会创建或重构应用的路由。该选项会使其从受支持的路径前缀解析区域设置，并在区域设置更改时更新路径名。默认区域设置不带前缀，例如 `/about`，而其他区域设置使用前缀，例如 `/es/about`。

在服务器端，[`gtMiddleware`](/docs/react/tanstack-start/reference/functions/gt-middleware) 会依次从 path、locale cookie、`Accept-Language` header 和 `defaultLocale` 解析区域设置。在客户端，更改区域设置时会在对应的路径名重新加载，并保留其 query string 和 hash。

TanStack Router 的 base path 会通过 `TSS_ROUTER_BASEPATH` 予以保留。

## 初始化路由器并配置 root 路由 [#root-route]

将 [`initializeGT`](/docs/react/reference/config#initialize) 的导入语句和初始化器添加到现有的 `src/router.tsx` 文件中：

```tsx title="src/router.tsx"
import { initializeGT } from 'gt-tanstack-start';
import gtConfig from '../gt.config.json';
import loadTranslations from '../loadTranslations';

initializeGT({ ...gtConfig, loadTranslations });
```

然后在 `src/routes/__root.tsx` 加载器中解析区域设置并加载翻译快照。将 `locale` 和 `translations` 传给 shell 组件中的 [`<GTProvider>`](/docs/react/reference/components/gt-provider)。

```tsx title="src/routes/__root.tsx"
import {
  HeadContent,
  Scripts,
  createRootRoute,
} from '@tanstack/react-router';
import {
  GTProvider,
  getLocale,
  getTranslationsSnapshot,
  LocaleSelector,
} from 'gt-tanstack-start';

export const Route = createRootRoute({
  loader: async () => {
    const locale = getLocale();
    return {
      locale,
      translations: await getTranslationsSnapshot(locale),
    };
  },
  shellComponent: RootDocument,
});

function RootDocument({ children }: { children: React.ReactNode }) {
  const { locale, translations } = Route.useLoaderData();
  return (
    <html lang={locale}>
      <head>
        <HeadContent />
      </head>
      <body>
        <GTProvider locale={locale} translations={translations}>
          <LocaleSelector />
          {children}
        </GTProvider>
        <Scripts />
      </body>
    </html>
  );
}
```

[`<GTProvider>`](/docs/react/reference/components/gt-provider) 需要同时提供 `locale` 和 `translations`——这与 Next.js 不同，后者由服务器端处理它们；也不同于 React Native，后者由 provider 自行加载它们。

[`initializeGT`](/docs/react/reference/config#initialize) 必须在 [`gtMiddleware`](/docs/react/tanstack-start/reference/functions/gt-middleware) 开始处理请求之前运行。请先完成路由器和 root 路由的设置，再启动开发服务器。

## 标记需翻译的内容 [#content]

在路由组件中，使用 [`<T>`](/docs/react/reference/components/t) 包裹 JSX，并通过 [`useGT`](/docs/react/reference/hooks/use-gt) 翻译字符串。请从 `gt-react` 导入它们，这样 CLI 在扫描源代码时才能识别到它们。

```tsx title="src/routes/index.tsx"
import { createFileRoute } from '@tanstack/react-router';
import { T, useGT } from 'gt-react';

export const Route = createFileRoute('/')({ component: Home });

function Home() {
  const gt = useGT();

  return (
    <main>
      <T>
        <h1>Welcome to my app</h1>
        <p>This content is translated automatically.</p>
      </T>
      <input aria-label={gt('Email input field')} />
    </main>
  );
}
```

## Sitemap

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