Альфа
Compiler от Lingo.dev находится в альфа-версии. Он нестабилен, не рекомендуется для использования в production, а API могут меняться от релиза к релизу.
Эти рекомендации основаны на подходах, которые помогают добиться надёжного и экономичного результата при работе с Compiler от Lingo.dev. Они охватывают пайплайн сборки, организацию кода, качество перевода и тестирование.
Пайплайн сборки#
Используйте стратегию из трёх режимов#
Dev — pseudotranslator
Включите dev.usePseudotranslator: true, чтобы получать мгновенную обратную связь. Никаких API-вызовов, никаких затрат, результат сразу. Псевдопереводы помогают находить непереведённые строки и проверять вёрстку.
{
buildMode: "translate",
dev: { usePseudotranslator: true },
}CI — режим перевода
Запускайте с buildMode: "translate" и реальным провайдером. После каждого прогона CI коммитьте обновлённый .lingo/metadata.json, чтобы переводы были доступны в production.
LINGO_BUILD_MODE=translate npm run buildProduction — режим только кэша
Разворачивайте с buildMode: "cache-only". В production API-ключи не нужны. Сборки будут детерминированными и быстрыми.
LINGO_BUILD_MODE=cache-only npm run buildКонтроль версий#
Коммитьте .lingo/ в репозиторий#
Файл .lingo/metadata.json — единый источник истины для всех закэшированных переводов. От него зависят production-сборки в режиме cache-only.
# .gitignore - do NOT ignore .lingo/
node_modules/
dist/
.envЕсли .lingo/metadata.json не закоммичен, production-сборки завершатся ошибкой, потому что в режиме cache-only будет неоткуда читать переводы.
Проверяйте диффы переводов#
Когда CI коммитит обновлённые переводы, проверяйте дифф .lingo/metadata.json в pull request. Так вы сможете заметить проблемы с переводом до того, как они попадут в production, — примерно так же, как при проверке изменений в коде.
Организация кода#
Размещайте переводимый текст прямо в JSX#
Compiler сканирует JSX в поисках переводимого контента. Текст, который хранится в переменных JavaScript, константах или внешних файлах, не обнаруживается:
// Good - compiler detects this text
export function Header() {
return <h1>Welcome to our app</h1>;
}
// Bad - compiler cannot detect text in a variable
const title = "Welcome to our app";
export function Header() {
return <h1>{title}</h1>;
}Используйте useDirective в больших кодовых базах#
В больших проектах сканирование каждого файла увеличивает время сборки. Включите useDirective: true и добавляйте 'use i18n' только в файлы с пользовательским текстом:
{
useDirective: true,
}'use i18n';
// Only this file is scanned for translations
export function PublicPage() {
return <h1>Welcome</h1>;
}Держите sourceRoot как можно уже#
Задайте для sourceRoot минимальный каталог, в котором находятся переводимые компоненты. Слишком широкий sourceRoot приводит к сканированию лишних файлов:
| Тип проекта | Рекомендуемый sourceRoot |
|---|---|
| Next.js App Router | "./app" |
| Vite + React | "src" |
| Monorepo (с useDirective) | "." |
Качество перевода#
Используйте manual overrides для терминов бренда#
Для названий брендов, продуктов и юридических текстов лучше использовать manual overrides, а не полагаться на AI-перевод:
<h1 data-lingo-override={{ es: "Motor de Localizacion", de: "Lokalisierungs-Engine" }}>
Localization Engine
</h1>Используйте сопоставление пар локалей для оптимизации затрат#
У разных моделей разные сильные стороны и стоимость. Назначайте более дорогие модели языкам, которым они действительно нужны, а в остальных случаях используйте более экономичные варианты:
{
models: {
"*:*": "groq:llama-3.3-70b-versatile", // Fast, cost-effective default
"*:ja": "anthropic:claude-3-5-sonnet", // Higher quality for Japanese
"*:zh-Hans": "anthropic:claude-3-5-sonnet", // Higher quality for Chinese
},
}Используйте движок локализации Lingo.dev для глоссария и тональности бренда#
Если вам нужна единая терминология во всём приложении, настройте в Lingo.dev движок локализации с glossary и тональность бренда. Они будут автоматически применяться к каждому запросу на перевод.
Плюрализация#
Отключайте плюрализацию, если она не нужна#
Если в вашем приложении рядом с текстом не выводятся числовые значения, отключите плюрализацию, чтобы упростить сборку:
{
pluralization: { enabled: false },
}Пишите текст, зависящий от количества, естественно#
Когда плюрализация включена, формулируйте текст с числовыми переменными естественно. Compiler сам преобразует его в ICU MessageFormat:
// Good - the compiler detects and pluralizes this
<p>You have {count} items in your cart</p>
// Also good - works with any numeric expression
<p>{unreadCount} unread messages</p>Тестирование#
Сначала тестируйте с pseudotranslator#
Прежде чем генерировать реальные переводы, запустите pseudotranslator, чтобы проверить полноту покрытия:
- Включите
dev.usePseudotranslator: true - Пройдите по каждой странице и каждому компоненту
- Любой текст без маркеров
[!!! ... !!!]не переводится - Исправьте проблемы с размещением текста: перенесите текст в JSX, скорректируйте
sourceRoot, добавьте директивы'use i18n'
Находить непереведённые строки с помощью pseudotranslator быстрее и дешевле, чем обнаруживать их уже после генерации реальных переводов.
Проверьте реальные переводы перед релизом#
Отключите pseudotranslator и перед релизом сгенерируйте реальные переводы как минимум для одной целевой локали:
{
dev: { usePseudotranslator: false },
}Проверьте переполнение вёрстки, обрезание текста и проблемы с двунаправленным текстом, которые псевдопереводы не показывают.
