Примеры проектов

Mike ShulgaИнженерUpdated 2 месяца назад · 3 min read

Каждый пример ниже — настоящий репозиторий с зафиксированными .lingo/config.json и готовыми переводами: читайте конфиг рядом с результатом, который он выдал. Большинство — рабочие приложения, пара существует только чтобы показать формат файла. Клонируйте или форкните любой, запустите lingo link, чтобы подключить свой движок, и пушьте.

Сначала выберите подход#

Есть два способа локализации с помощью CLI — от этого зависит, какие примеры окажутся полезными именно вам.

Переводите файлы, которые у вас уже есть. Фреймворк хранит переводы в своём формате — Rails YAML, Android XML, Laravel PHP, ARB, Markdown — и CLI переводит эти файлы прямо на месте. Код трогать не нужно. Именно так устроены девять из одиннадцати примеров ниже.

Работа без ключей. Оберните строки в l.text(...) там, где они встречаются, — lingo extract сам создаст каталог с хеш-ключами, и придумывать или поддерживать ключи переводов не придётся. Это добавляет шаг сборки и пакет времени выполнения — именно так работают два примера для веб-приложений.

Мобильные приложения#

ПримерФорматПочему именно этот
iOSxcode-xcstringsString Catalog хранит все локали, поэтому целевой путь совпадает с исходным.
AndroidandroidЧистый values/ как источник и стандартные квалификаторы Android (values-pt-rBR/)
FlutterflutterМетаданные @ и ICU-плейсхолдеры сохраняются, @@locale переписывается для каждого файла

Веб-приложения#

Два примера без ключей. В обоих строки обёрнуты в l.text(...), каталог генерируется через lingo extract — поэтому в среднем столбце указан пакет времени выполнения, а не формат файла.

ПримерПакетПочему именно этот
React + Vite@lingo.dev/reactБез ключей: сгенерированные объявления сужают l.text() до извлечённых строк
Next.js@lingo.dev/react-nextАвторинг без ключей, маршрутизация по локали, hreflang и переключатель — Pages Router

hreflang в продакшне

LingoHead формирует URL hreflang из пропа baseUrl, который по умолчанию пустой, — поэтому теги содержат относительные адреса. Поисковики ожидают абсолютные URL — передайте origin своего сайта (<LingoHead baseUrl="https://example.com" />), прежде чем на них полагаться.

Контент и спецификации#

ПримерФорматПочему именно этот
Markdown docsmd, mdxТекст по умолчанию; поля frontmatter и MDX-пропсы — по выбору
Markdocmarkdoc, jsonКонтент Next.js и строки интерфейса в одном пуше — три записи, каждая с разными параметрами
OpenAPIyaml-openapiТолько заголовки и описания; пути, идентификаторы операций и перечисления не трогаются

Каталоги фреймворков#

ПримерФорматПочему именно этот
Railsyaml-root-keyЛокаль — корневой ключ YAML, поэтому он тоже перезаписывается
Laravelphp, poКаталоги Laravel плюс файл gettext; плейсхолдеры :name сохраняются в обоих
TypeScript modulestypescriptКаталоги в виде TypeScript-модулей вместо JSON. Только формат — никакое приложение их не использует

Для каталогов TypeScript нужен экспорт по умолчанию

Формат typescript читает default-экспорт — export default { … }, с as const или без. Именованный экспорт не даёт переводимого контента, и запуск завершается, просто скопировав исходный текст. Если пуш сообщает о локализованных файлах, но выходных токенов почти ноль — сначала проверьте форму экспорта.

Как использовать примеры#

bash
npm install -g @lingo.dev/cli
lingo login
lingo link          # writes your own orgId and engineId into .lingo/config.json
lingo push --wait

Ни в одном из примеров не зафиксированы orgId и engineId — чтобы форк случайно не отправил запрос через чужой движок. lingo link заполняет оба локально.

Если хотите использовать GitHub App вместо CLI

GitHub App читает engineId из файла .lingo/config.json в вашем репозитории — организация определяется по установке App, но движок должен быть указан в файле. После форка запустите lingo link и закоммитьте обновлённый конфиг перед установкой App.

Примеры есть не для каждого формата#

Эти одиннадцать примеров охватывают Фреймворки, о которых спрашивают чаще всего, но CLI переводит восемнадцать форматов. xliff, srt, Xcode .strings и .stringsdict, универсальный yaml, а также обычные JSON/JSONC работают без репозитория здесь — полный список и нужная Конфигурация для каждого формата есть в разделе Formats.

Следующие шаги#