# General Translation React SDKs (gt-react, gt-next, gt-react-native): Быстрый старт SPA для React
URL: https://generaltranslation.com/ru/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">
  **Совет:** Запустите `npx gt@latest`, чтобы настроить загрузочный модуль Vite и загрузку переводов с помощью [мастера настройки](/docs/cli/quickstart). В этом руководстве описана ручная настройка.
</Callout>

<Callout type="info">
  **Примечание:** Если ваше приложение рендерится на сервере, используйте вместо этого руководство [Быстрый старт React](/docs/react/react-quickstart).
</Callout>

## Выберите бандлер [#bundlers]

В примерах ниже используется Vite. Если вы используете другую систему сборки, обратитесь к её руководству по настройке точки входа, загрузочного модуля и загрузчика переводов:

<Cards>
  <Card title="Vite" href="/docs/react/guides/spa/configuring-vite-spa">
    Настройте HTML-точку входа Vite и загрузку переводов.
  </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 и резервные варианты для целевого output.
  </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 сканирует файлы JavaScript и TypeScript в каталогах `src`, `app`, `pages` и `components`. Укажите [`src`](/docs/cli/reference/config#src), если ваш исходный код находится в другом месте.

<Callout type="info">
  **Примечание:** Бандлеры, такие как 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 {};
  }
}
```

Эта функция загружает JSON-файлы перевода из каталога `src/_gt/`. CLI создаёт эти файлы при запуске [`npx gt translate`](/docs/cli/reference/commands/translate).

<Callout type="info">
  **Rollup:** Обычный Rollup не может проанализировать полностью динамический импорт выше. Вместо этого используйте [статическую карту locale-loader](/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"
        }
      }
    }
    ```

    Загрузите файл по HTTP с помощью `PUBLIC_URL`:

    ```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">
      **Предупреждение:** Не подключайте `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`, чтобы он указывал на новую точку входа: измените его `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](/docs/react/guides/developing-spa-translations), чтобы добавить компилятор и учётные данные для разработки.
</Callout>

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

Теперь оберните любой текст, который нужно перевести, в компонент **[`<T>`](/docs/react/reference/components/t)**. [`<T>`](/docs/react/reference/components/t) означает «translate»:

```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` сохраняет этот выбор в cookie-файл `generaltranslation.locale` и перезагружает страницу — затем [`initializeGTSPA`](/docs/react/reference/config#initialize-spa) снова выполняется и загружает переводы для новой локали до отрисовки приложения.

### 7. Пройдите аутентификацию и переведите

Перед переводом пройдите аутентификацию в General Translation:

```bash
npx gt auth
```

Следуйте подсказкам, чтобы создать аккаунт или войти в систему. Когда появится запрос на выбор типа ключа, выберите ключ для production. Команда сгенерирует API-ключ и 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">
  **Предупреждение:** не коммитьте `.env.local` и не раскрывайте `GT_API_KEY` в браузерном коде.
</Callout>

Затем выполните команду `translate`, чтобы сгенерировать файлы перевода для всех настроенных локалей:

```bash
npx gt translate
```

CLI сканирует ваше приложение, переводит его содержимое и записывает результат по пути вывода, указанному в `gt.config.json`. Запускайте его снова всякий раз, когда меняется исходное содержимое.

### 8. Запуск и проверка

Отрендерите пример компонента в своём приложении:

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

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

Запустите сервер разработки вашего приложения (например, `npm run dev` в Vite), откройте локальный URL и выберите `es`, `fr` или `ja`. Убедитесь, что страница перезагружается, а заголовок отображается на выбранном языке.

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

<Accordions>
  <Accordion title="Язык не меняется, когда я выбираю его в выпадающем списке">
    Убедитесь, что в браузере включены cookie-файлы, выбранная локаль указана в `gt.config.json` и [`initializeGTSPA`](/docs/react/reference/config#initialize-spa) завершается до загрузки входного модуля приложения.
  </Accordion>

  <Accordion title="Некоторые переводы неточны">
    Неоднозначный текст может приводить к неточным переводам. Например, &quot;apple&quot; может означать фрукт или компанию. Добавьте проп `$context`, чтобы уточнить контекст:

    ```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.
