Структура проекта
Понимание директории .lingo/ и её содержимого.
Обзор директорий
Когда вы впервые запускаете компилятор, он создаёт директорию .lingo/ в корне вашего проекта:
your-project/
├── .lingo/
│ ├── metadata.json
│ ├── locale-resolver.server.ts (optional)
│ └── locale-resolver.client.ts (optional)
├── src/
├── package.json
└── ...
metadata.json
Основной файл, содержащий все данные переводов.
Структура
{
"version": "1",
"sourceLocale": "en",
"targetLocales": ["es", "de", "fr"],
"translations": {
"abc123def456": {
"source": "Welcome to our app",
"context": {
"file": "app/page.tsx",
"line": 12,
"component": "HomePage"
},
"locales": {
"es": "Bienvenido a nuestra aplicación",
"de": "Willkommen in unserer App",
"fr": "Bienvenue dans notre application"
},
"metadata": {
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
}
}
}
Ключевые поля
Version: Версия формата метаданных. Текущая: "1"
Source/Target Locales: Настроенные локали
Translations: Хеш-таблица всех переводимых строк:
- Hash (
abc123def456): Стабильный идентификатор на основе исходного текста и контекста - source: Оригинальный английский текст
- context: Где этот текст используется (файл, строка, компонент)
- locales: Переводы для каждой целевой локали
- metadata: Когда перевод был создан или обновлён
Генерация хеша
Хеши детерминированы:
- Основаны на исходном тексте и контексте компонента
- Один и тот же текст в разных местах = разные хеши
- Обеспечивает контекстно-зависимые переводы
Пример:
// app/home/page.tsx
<button>Submit</button> // Hash: abc123
// app/checkout/page.tsx
<button>Submit</button> // Hash: def456 (different context)
Кастомные резолверы локалей
Необязательные файлы для кастомизации определения и сохранения локали.
locale-resolver.server.ts
Определение локали на сервере (только для Next.js):
// .lingo/locale-resolver.server.ts
export async function getServerLocale(): Promise<string> {
// Your custom logic
return "en";
}
locale-resolver.client.ts
Определение и сохранение локали на клиенте:
// .lingo/locale-resolver.client.ts
export function getClientLocale(): string {
// Detect locale
return "en";
}
export function persistLocale(locale: string): void {
// Save locale preference
}
Если эти файлы отсутствуют, компилятор использует стандартное поведение на основе cookie.
Подробнее см. в разделе Пользовательские резолверы локалей.
Контроль версий
Стоит ли коммитить .lingo/?
Да. Каталог .lingo/ должен находиться под контролем версий:
Коммитить:
metadata.json— содержит все переводы- Пользовательские резолверы локалей (если созданы)
Не коммитить:
- Ничего — все файлы в
.lingo/должны быть закоммичены
Зачем коммитить переводы?
- Контроль версий — отслеживайте изменения переводов вместе с кодом
- Совместная работа — делитесь переводами с командой
- CI/CD — продакшн-сборки используют закоммиченные переводы
- История изменений — видно, когда и почему менялись переводы
Интеграция с Git
Добавьте .lingo/ в свой репозиторий:
git add .lingo/
git commit -m "chore: update translations"
git push
Компилятор автоматически обновляет .lingo/metadata.json, когда:
- Добавляется новый переводимый текст
- Изменяется существующий текст
- Генерируются переводы
Регулярно коммитьте эти обновления.
Размер файла
metadata.json увеличивается вместе с вашим приложением:
- Маленькое приложение (50 строк): ~10 КБ
- Среднее приложение (500 строк): ~100 КБ
- Большое приложение (5000 строк): ~1 МБ
Это нормально и допустимо для контроля версий.
Очистка
Удаление неиспользуемых переводов
Со временем могут накапливаться неиспользуемые переводы (от удалённых компонентов).
Ручная очистка:
- Найдите хеш в кодовой базе
- Если не найден — удалите из
metadata.json
Автоматическая очистка (скоро появится):
npx @lingo.dev/compiler clean
Это позволит автоматически удалять неиспользуемые переводы.
Сбросить переводы
Чтобы сгенерировать все переводы заново:
# Backup current translations
cp .lingo/metadata.json .lingo/metadata.backup.json
# Delete metadata
rm .lingo/metadata.json
# Regenerate
npm run dev # or npm run build
Миграция
С старого компилятора
В старом компиляторе использовалась другая структура файлов:
Старая:
lingo/
├── dictionary.js
├── meta.json
└── [locale]/
└── *.json
Новая:
.lingo/
└── metadata.json
Миграция не автоматизирована. Подробнее см. в руководстве по миграции.
Проверка переводов
Просмотр в редакторе
Откройте .lingo/metadata.json в редакторе:
{
"translations": {
"abc123": {
"source": "Welcome",
"locales": {
"es": "Bienvenido"
}
}
}
}
Поиск перевода
Найдите перевод по исходному тексту:
grep -r "Welcome" .lingo/metadata.json
Поиск по хэшу
grep -r "abc123" .lingo/metadata.json
Красивый вывод
cat .lingo/metadata.json | jq '.'
Частые вопросы
Можно ли вручную редактировать metadata.json?
Да, но не рекомендуется. Лучше использовать data-lingo-override — так безопаснее, и изменения отслеживаются в исходном коде.
Что если я удалю metadata.json? Компилятор пересоздаст его при следующей сборке. Все переводы будут сгенерированы заново (это расходует API-кредиты).
Могу ли я переместить .lingo/ в другую папку?
Да. Настройте это через опцию lingoDir:
{
lingoDir: "translations"
}
Содержит ли metadata.json конфиденциальные данные? Нет. В нём только исходный текст и переводы — никаких API-ключей или секретов.
Можно ли объединять metadata.json из разных веток? Да. Git сам справляется с мержами. Конфликты бывают редко (хэши уникальны).
Что если две ветки добавят один и тот же перевод? Git объединит их автоматически. Если хэши разные (разный контекст), оба варианта сохранятся.
Дальше
- Custom Locale Resolvers — настройка хранения
- Development Tools — работа с псевдопереводчиком
- Build Modes — как работает кэширование