# General Translation React SDKs (gt-react, gt-next, gt-react-native): Быстрый старт с React Router
URL: https://generaltranslation.com/ru/docs/react/react-router-quickstart.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Добавьте General Translation в приложение на фреймворке React Router, включая витрины Shopify Hydrogen, и переведите первый контент.

В режиме фреймворка React Router `gt-react` подключается через корневой маршрут. Библиотека инициализируется в `app/root.tsx`, локаль каждого посетителя разрешается в корневом загрузчике, а [`GTProvider`](/docs/react/reference/components/gt-provider) отображается в корневом `Layout`.

Это руководство предназначено для приложений, созданных с помощью `@react-router/dev`. Если вы используете React Router как библиотеку в одностраничном приложении на Vite, воспользуйтесь руководством [Быстрый старт SPA для React](/docs/react/react-spa-quickstart).

Чтобы автоматизировать настройку, выполните [`npx gt@latest init`](/docs/cli/reference/commands/init) в корневом каталоге приложения. Мастер установит `gt-react`, создаст конфигурацию и загрузчик переводов, а также настроит `app/root.tsx`, созданный из стартового шаблона create-react-router или Hydrogen. Остальные корневые файлы он не изменяет, а выводит список действий, которые нужно выполнить вручную. В этом руководстве та же настройка описана пошагово вручную.

*Примечание: для этой настройки требуется `gt-react` версии 11.1.3 или новее, а приложение должно выполнять рендеринг при каждом запросе. Режим SPA (`ssr: false`), предварительный рендеринг и RSC Framework Mode не поддерживаются.*

## Быстрый старт [#quickstart]

### 1. Установите пакеты

`gt-react` — библиотека, которая отвечает за переводы в вашем приложении. `gt` — CLI, который их генерирует.

<Tabs items={['npm', 'yarn', 'bun', 'pnpm']}>
  <Tab value="npm">
    ```bash
    npm install gt-react && npm install gt --save-dev
    ```
  </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`

Создайте файл `gt.config.json` в корневом каталоге проекта. В нём задаются язык-источник, целевые локали и каталог, в который записываются файлы перевода.

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

* `defaultLocale` — язык, на котором написано ваше приложение.
* `locales` — языки, на которые нужно перевести приложение. Выберите их из списка [поддерживаемых локалей](/docs/platform/dashboard/reference/supported-locales).
* `files.gt.output` — путь, по которому CLI записывает файлы перевода. Размещайте их в `app/`, чтобы Vite включал их в бандлы вместе с серверным и клиентским кодом.

### 3. Создайте загрузчик переводов

Создайте файл `app/loadTranslations.ts`. Он импортирует файл перевода нужной локали по запросу корневого загрузчика.

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

Затем создайте пустой файл `{}` для каждой целевой локали, например `app/_gt/es.json` и `app/_gt/ja.json`; [`gt init`](/docs/cli/reference/commands/init) создаёт их автоматически. Локаль без файла перевода отображается на языке по умолчанию.

### 4. Настройте корневой маршрут

Вызовите [`initializeGT`](/docs/react/reference/config#initialize) один раз в области видимости модуля в `app/root.tsx`, верните локаль и снимок переводов из корневого загрузчика и оберните содержимое `Layout` в [`GTProvider`](/docs/react/reference/components/gt-provider). Добавьте выделенные строки в существующий корневой файл:

```tsx title="app/root.tsx"
import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
  useRouteLoaderData, // [!code ++]
} from 'react-router';
import { GTProvider, getTranslationsSnapshot, initializeGT, parseLocale } from 'gt-react'; // [!code ++]

import type { Route } from './+types/root';
import gtConfig from '../gt.config.json'; // [!code ++]
import loadTranslations from './loadTranslations'; // [!code ++]
import './app.css';

initializeGT({ ...gtConfig, loadTranslations }); // [!code ++]

// [!code ++:11]
// У страниц ошибок нет данных загрузчика. Там GTProvider пропускается, чтобы он
// не заменил сохранённую локаль посетителя локалью по умолчанию.
function RootGTProvider({ children }: { children: React.ReactNode }) {
  const data = useRouteLoaderData<typeof loader>('root');
  if (!data) return <>{children}</>;
  return (
    <GTProvider locale={data.locale} translations={data.translations}>
      {children}
    </GTProvider>
  );
}

// [!code ++:4]
export async function loader({ request }: Route.LoaderArgs) {
  const locale = parseLocale(request);
  return { locale, translations: await getTranslationsSnapshot(locale) };
}

export function Layout({ children }: { children: React.ReactNode }) {
  const locale = useRouteLoaderData<typeof loader>('root')?.locale ?? gtConfig.defaultLocale; // [!code ++]
  return (
    // [!code ++]
    <html lang={locale}>
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        {/* [!code ++] */}
        <RootGTProvider>
          {children}
          <ScrollRestoration />
        {/* [!code ++] */}
        </RootGTProvider>
        <Scripts />
      </body>
    </html>
  );
}

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

`parseLocale` считывает cookie-файл локали, затем заголовок `Accept-Language`, а если определить локаль не удаётся, использует резервное значение `defaultLocale`. Если в корневом маршруте уже есть `loader`, добавьте `locale` и `translations` в возвращаемый им объект.

*Примечание: страницы ошибок, для которых нет данных корневого загрузчика (например, при прямом переходе на 404 или при ошибке в корневом загрузчике), рендерятся без [`GTProvider`](/docs/react/reference/components/gt-provider). Компоненты перевода и хуки, такие как [`<T>`](/docs/react/reference/components/t) и [`useLocale`](/docs/react/reference/hooks/use-locale), в этом случае выбрасывают исключение, и страница ошибки превращается в ошибку сервера, поэтому не используйте перевод в корневом `ErrorBoundary`.*

### 5. Отметьте контент для перевода

Оберните JSX в компонент [`<T>`](/docs/react/reference/components/t), чтобы перевести его на месте, а для обычных строк, например значений `aria-label`, используйте [`useGT`](/docs/react/reference/hooks/use-gt). Добавьте [`<LocaleSelector>`](/docs/react/reference/components/locale-selector), чтобы посетители могли переключать язык.

```tsx title="app/routes/home.tsx"
import { LocaleSelector, T, useGT } from 'gt-react';

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

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

Когда посетитель выбирает язык, [`<LocaleSelector>`](/docs/react/reference/components/locale-selector) сохраняет его в cookie-файле локали и перезагружает страницу, после чего корневой загрузчик отображает контент в новой локали.

### 6. Создайте переводы

Выполните вход с помощью [`gt login`](/docs/cli/reference/commands/login), укажите [`projectId`](/docs/cli/reference/config#project-id) существующего проекта в `gt.config.json` или задайте `GT_PROJECT_ID` в переменных окружения, а затем запустите перевод:

```bash
npx gt login
GT_PROJECT_ID=your-project-id npx gt translate
```

Вход в систему не выбирает проект автоматически. Если проекта у вас ещё нет, создайте его в [Dashboard](/docs/platform/dashboard/get-started) или выполните [`gt init`](/docs/cli/reference/commands/init) и включите живой перевод для разработки, чтобы выбрать или создать проект.

Запустите сервер разработки и переключите язык, чтобы увидеть переводы. Добавьте эту команду в начало существующего скрипта сборки, чтобы сборки для production всегда включали актуальные переводы:

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

Чтобы загружать переводы из CDN, а не включать их в бандл, выполните [`npx gt configure --storage cdn`](/docs/cli/reference/commands/configure). Команда покажет, какое изменение нужно внести в `app/root.tsx`.

Если вы кэшируете ответы с HTML-документами, например в CDN или на обратном прокси, разделяйте кэш по локали, чтобы посетители не получали страницу на чужом языке. Отправляйте в таких ответах заголовок `Vary: Cookie, Accept-Language` либо исключите их из общих кэшей.

<Callout type="info">
  **Примечание:** для CI передайте через настройки секретов отдельный `GT_API_KEY` с ограниченной областью доступа и тот же ID проекта (см. [учётные данные CLI](/docs/cli/guides/configuring#credentials)).
</Callout>

## Shopify Hydrogen [#hydrogen]

Витрины Hydrogen — это приложения на фреймворке React Router, поэтому для них подходят те же шаги. Оставьте собственную команду сборки Hydrogen и добавьте перед ней генерацию переводов:

```json title="package.json"
{
  "scripts": {
    "build": "npx gt translate && shopify hydrogen build --codegen"
  }
}
```

`gt-react` переводит текст в коде вашей витрины: навигацию, кнопки и тексты страниц. Названия и описания товаров, а также прочий контент магазина поступают из Shopify, поэтому переводите их в Shopify.

## Устранение неполадок [#troubleshooting]

<Accordions>
  <Accordion title="gt init оставил app/root.tsx без изменений">
    Мастер изменяет только корневые файлы, которые по структуре соответствуют стартовым шаблонам create-react-router или Hydrogen и ещё не вызывают [`initializeGT`](/docs/react/reference/config#initialize). Чтобы внести изменения вручную, выполните [шаг 4](#quickstart).
  </Accordion>

  <Accordion title="gt init остановился, не внеся изменений">
    Способ решения зависит от причины:

    * **Режим SPA, предварительный рендеринг или RSC Framework Mode:** в этой конфигурации локаль каждого посетителя считывается в корневом загрузчике при каждом запросе, поэтому эти режимы не поддерживаются — ни мастером, ни при ручной настройке.
    * **Диапазон версий `gt-react`, допускающий версии ниже 11.1.3:** обновите `gt-react` и снова выполните `npx gt@latest init`.
    * **`appDirectory`, отличный от `app`, или `react-router.config`, который мастер не может прочитать:** если приложение выполняет рендеринг при каждом запросе, выполните `npx gt@latest init --no-react-setup`, чтобы настроить всё, кроме исходного кода, а затем выполните шаги 2–4, указав вместо `app/` свой каталог приложения, в том числе в `files.gt.output`.
  </Accordion>

  <Accordion title="Язык не меняется при использовании селектора">
    Убедитесь, что cookie-файлы включены, локаль указана в `gt.config.json`, а селектор отображается внутри `RootGTProvider`. Если `<html lang>` меняется, а текст — нет, выполните [`npx gt translate`](/docs/cli/reference/commands/translate), чтобы заполнить `app/_gt/[locale].json`.
  </Accordion>
</Accordions>

## Next steps

- /docs/react/guides/translating-jsx
- /docs/react/guides/translating-strings
- /docs/react/guides/managing-locales
- /docs/react/guides/storing-translations

## Sitemap

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