Лучшие практики

Рекомендуемые паттерны и рабочие процессы для @lingo.dev/compiler.

Рабочий процесс разработки

Используйте псевдопереводчик по умолчанию

Делай так:

{
  dev: {
    usePseudotranslator: true, // Fast, free, instant feedback
  }
}

Почему:

  • Мгновенная обратная связь — без задержек API
  • Никаких затрат — не тратятся кредиты API
  • Визуальные маркеры показывают, что переводится
  • Тестирует UI с разной длиной текста

Отключайте только при проверке качества реального перевода.

Разделяйте разработку, CI и продакшн

Разработка:

{
  buildMode: "translate",
  dev: {
    usePseudotranslator: true,
  }
}

CI:

{
  buildMode: "translate",
  dev: {
    usePseudotranslator: false,
  }
}

Продакшн:

{
  buildMode: "cache-only",
}

Этот процесс:

  • Делает разработку быстрой и дешёвой
  • Генерирует реальные переводы в CI при каждом деплое
  • Делает продакшн-сборки предсказуемыми и быстрыми

Стратегия перевода

Доверьте большую часть переводов ИИ

Делай так:

<p>Welcome to our application</p>

Не делай так:

<p data-lingo-override={{ es: "...", de: "...", fr: "..." }}>
  Welcome to our application
</p>

Используйте ручные правки только для:

  • Названий брендов
  • Технических терминов, требующих конкретного перевода
  • Юридических текстов, требующих заверения
  • Маркетинговых текстов, нуждающихся в ручной проверке

Используйте ручные правки последовательно

Делай так:

// Consistent brand name across app
<h1 data-lingo-override={{ es: "Lingo.dev", de: "Lingo.dev" }}>
  Lingo.dev
</h1>

<p>
  Welcome to <span data-lingo-override={{ es: "Lingo.dev", de: "Lingo.dev" }}>
    Lingo.dev
  </span>
</p>

Не делайте так:

<h1 data-lingo-override={{ es: "Lingo.dev" }}>Lingo.dev</h1>
<p>Welcome to Lingo.dev</p> // Missing override—inconsistent

Конфигурация

Начните с простого

Делайте так:

{
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
}

Не делайте так:

{
  sourceLocale: "en",
  targetLocales: ["es", "de", "fr", "pt", "it", "ja", "zh", "ar", "ru", "ko"],
  models: {
    "en:es": "groq:...",
    "en:de": "google:...",
    // Complex mappings for 10 locales
  },
  prompt: "Long custom prompt...",
  pluralization: { enabled: false },
}

Начните с 2-3 целевых локалей. Добавляйте больше по мере необходимости. Не занимайтесь преждевременной оптимизацией.

Используйте движок Lingo.dev

Делайте так:

{
  models: "lingo.dev" // Simple, optimized, supports all features
}

Не делайте так:

{
  models: {
    "*:*": "groq:...", // Requires manual model selection
  }
}

Движок Lingo.dev предоставляет:

  • Автоматический выбор модели
  • Обработка fallback
  • Translation memory
  • Поддержка глоссария

Используйте прямых LLM-провайдеров только если нужен полный контроль или оптимизация затрат.

Определение локали

Делайте так:

{
  localePersistence: {
    type: "cookie",
    config: {
      name: "locale",
      maxAge: 31536000,
    },
  },
}

Когда кастомизировать:

  • Нужен localStorage (SPA)
  • Маршрутизация через URL (/en/about)
  • Маршрутизация через поддомен (es.example.com)
  • Предпочтения пользователя в базе данных

Реализуйте Custom Locale Resolvers только если стандартные не подходят.

Контроль версий

Коммитьте директорию .lingo/

Делайте так:

git add .lingo/
git commit -m "chore: update translations"
git push

Почему:

  • Система контроля версий отслеживает изменения переводов
  • Team делится переводами
  • CI/CD использует закоммиченные переводы
  • Для production-сборок не нужны API-ключи

Коммит после запуска CI

Делайте так (в CI):

- name: Generate translations
  run: npm run build

- name: Commit translations
  run: |
    git add .lingo/
    git commit -m "chore: update translations" || exit 0
    git push

Это гарантирует, что production-сборки всегда используют актуальные переводы.

CI/CD

Генерируйте переводы в CI

Делайте так:

# GitHub Actions
- name: Generate translations
  env:
    LINGODOTDEV_API_KEY: ${{ secrets.LINGODOTDEV_API_KEY }}
  run: npm run build

Не делайте так:

# Production build without API key
- name: Build
  run: npm run build # Fails if translations missing

Генерируйте переводы в CI, где есть API-ключи. Production-сборки используют кэшированные переводы.

Используйте только кэш в production

Делайте так:

# Production build
LINGO_BUILD_MODE=cache-only npm run build

Не делайте так:

# Production build with translate mode
LINGO_BUILD_MODE=translate npm run build # Non-deterministic, requires API keys

Производительность

Включайте плюрализацию выборочно

Делайте так (если используете формы во множественном числе):

{
  pluralization: {
    enabled: true,
  }
}

Делайте так (если не используете формы во множественном числе):

{
  pluralization: {
    enabled: false, // Skip plural detection—faster builds
  }
}

Плюрализация добавляет небольшую нагрузку (один LLM-запрос на каждый текст с числами). Отключайте, если не нужно.

Используйте быстрые модели для плюрализации

Делайте так:

{
  pluralization: {
    enabled: true,
    model: "groq:llama-3.1-8b-instant", // Fast, cheap
  }
}

Не делайте так:

{
  pluralization: {
    model: "openai:gpt-4o", // Expensive overkill for plural detection
  }
}

Оптимизируйте сопоставление пар локалей

Делайте так (оптимизация затрат):

{
  models: {
    "en:es": "groq:llama-3.3-70b-versatile", // Fast & cheap
    "en:ja": "openai:gpt-4o", // High quality for complex language
    "*:*": "lingo.dev", // Fallback
  }
}

Используйте быстрые/дешёвые модели для похожих языков (романские, германские). Для сложных языков (CJK, арабский) используйте высококачественные модели.

Тестирование

Сначала тестируйте с псевдопереводчиком

Делайте так:

  1. Включите псевдопереводчик
  2. Проверьте все UI-компоненты
  3. Исправьте проблемы с версткой (переполнение, обрезка)
  4. Затем генерируйте реальные переводы

Почему:

  • Псевдопереводы мгновенные
  • Сразу видны проблемы с версткой
  • Экономит расходы на API

Тестируйте все целевые локали

Делайте так:

// Test with locale switcher
<LanguageSwitcher /> // Switch between all locales

// Or manually test
setLocale("es"); // Spanish
setLocale("de"); // German
setLocale("fr"); // French

Проверьте каждую локаль:

  • Переводы отображаются корректно
  • Верстка учитывает длину текста
  • Нет непереведённого текста
  • RTL-языки отображаются правильно (если применимо)

Обработка ошибок

Корректно обрабатывайте отсутствие переводов

Компилятор завершает сборку с ошибкой, если нет переводов. Это сделано специально — лучше поймать отсутствие переводов заранее, чем выпустить сломанную UI.

Если сборка не удалась:

  1. Запустите с buildMode: "translate", чтобы сгенерировать недостающие переводы
  2. Зафиксируйте .lingo/metadata.json
  3. Повторите сборку для продакшена с buildMode: "cache-only"

Следите за ошибками перевода

В CI проверяйте ошибки перевода:

- name: Generate translations
  run: npm run build 2>&1 | tee build.log

- name: Check for translation errors
  run: |
    if grep -q "Failed to generate translation" build.log; then
      echo "Translation generation failed"
      exit 1
    fi

Обслуживание

Регулярная очистка

Периодически удаляйте неиспользуемые переводы:

# Backup first
cp .lingo/metadata.json .lingo/metadata.backup.json

# Manual: Search for each hash in codebase, remove if not found

# Automated (coming soon):
npx @lingo.dev/compiler clean

Следите за размером файла

.lingo/metadata.json увеличивается вместе с вашим приложением. Если он становится большим (>5 МБ):

  • Разделите на несколько приложений
  • Архивируйте старые переводы
  • Используйте автоматическую очистку

Частые анти-паттерны

Не злоупотребляйте оверрайдами

Плохо:

<p data-lingo-override={{ es: "...", de: "...", fr: "..." }}>
  Welcome to our app
</p>

Пусть ИИ обрабатывает обычный текст. Оверрайды нужны только для исключений.

Не коммитьте API-ключи

Плохо:

// next.config.ts
{
  models: "lingo.dev",
  apiKey: "your-api-key-here", // NEVER commit API keys
}

Хорошо:

# .env (not committed)
LINGODOTDEV_API_KEY=your_key_here

Не используйте режим translate в продакшене

Плохо:

// production config
{
  buildMode: "translate", // Non-deterministic, requires API keys
}

Хорошо:

{
  buildMode: "cache-only", // Deterministic, no API keys
}

Не пропускайте контроль версий

Плохо:

# .gitignore
.lingo/ # DON'T ignore translations

Хорошо:

# .gitignore
.env # Ignore API keys only

Стратегия миграции

Плавный запуск

Когда добавляешь компилятор в существующее приложение:

  1. Начни с 1-2 локалей
  2. Включи псевдопереводчик
  3. Проверь все страницы
  4. Исправь проблемы с версткой
  5. Добавь ещё локали
  6. Сгенерируй реальные переводы
  7. Задеплой

Не пытайся перевести 20 локалей в первый же день.

Пошаговое внедрение

Не обязательно переводить всё приложение сразу:

{
  useDirective: true, // Opt-in per file
}

Добавь директиву 'use i18n' в те файлы, которые хочешь перевести:

'use i18n'; // This file gets translated

export function HomePage() {
  return <h1>Welcome</h1>;
}

Остальные файлы останутся без перевода, пока ты их не включишь.

Дальше