Migrating from Intlayer
Moving from Intlayer? This command brings your existing translation dictionaries and the simplest translation usage in your app into ai-i18n-tools. It makes safe updates automatically, then creates a clear report for anything that still needs your attention. This lets you move over gradually without needing to understand every difference upfront.
Already using i18next JSON translation files? You do not need this migration command; use the JSON pipeline instead.
What migrate-intlayer does
- Parses
*.content.tsdefault exports (key+content+t({ locale: '…' })leaves). - Seeds
ui.stringsJsonand per-locale files underui.flatOutputDirfrom the source-locale text and any translations already in the dictionary. Imported rows have nomodelsfield (they were not machine-translated by this run). - Rewrites safe call sites:
binding.path.to.leaf.value→t('English source')binding.path.value.replace('{token}', expr)→t('English {{token}}', { token: expr })
- Leaves everything else (dynamic keys, JSX spreads, chained
.replace().replace(), destructuring) untouched. The report lists each of those sites with the exact expression, a concretet()or JSX replacement, and theimport { t } from '…';line to add. - Dry run by default. Pass
--writeto apply catalog seeding and safe rewrites. The report is always written. It also lists dictionary files and leftoveruseIntlayer/IntlayerProviderusage to delete after the manual rewrites, catalog keys that still needextractthentranslate-ui, and a runtime bootstrap to paste over the app's i18n module.
Migrate your project
Install
ai-i18n-tools(see Installation). If your project has noai-i18n-tools.config.jsonyet, scaffold one:bashai-i18n-tools init [-P <provider>]Edit
sourceLocaleandtargetLocalesto match the locales already in your Intlayer dictionaries, and setui.sourceRoots,ui.stringsJson,ui.flatOutputDirto point at your app's source and desired catalog paths — same keystranslate-uiuses, see UI strings — Step 1: Initialise.Dry run first:
ai-i18n-tools migrate-intlayer(no--write). Readmigrate-intlayer-report.mdto see what it finds and which call sites need manual review before any file changes.ai-i18n-tools migrate-intlayer --writeto seedui.stringsJson/ui.flatOutputDirand rewrite the safe call sites.Give the regenerated report
migrate-intlayer-report.mdto an AI coding agent (recommended), or work through it yourself by following the steps:- The report ends with a Step-by-step TODO: finish each manual-review site with the concrete
t('…')/JSX shown there, add theimport { t } from '…';line, then delete the leftover*.content.tsfiles anduseIntlayer/IntlayerProviderusage the report lists. - Paste the report's runtime bootstrap over your app's i18n module. In the locale control, call
loadLocale(next)and theni18n.changeLanguage(next)—loadLocaleonly registers the flat bundle and does not switch the active language. - Run
ai-i18n-tools extractthenai-i18n-tools translate-ui(orsync) for any source strings the report marks as new.extractalso writesui-languages.json, which the bootstrap imports, so run it before starting the app even when no new string was added. Do not hand-editstrings.json, the flat locale files, orui-languages.json— those commands own them. - Once the report's cleanup list is complete and the app runs on ai-i18n-tools, remove the
intlayer/react-intlayerdependencies and the dictionary files.
- The report ends with a Step-by-step TODO: finish each manual-review site with the concrete
Run the example
The steps above apply to any Intlayer project. The intlayer-migration example walks through them on a small Vite + React app with basic (auto-rewritable) and complex (manual-review) cases, so you can see the report and the runtime bootstrap before trying it on your own code. intlayer-pristine/ is never modified; src/ is the working copy.
npx degit wsj-br/ai-i18n-tools/examples/intlayer-migration intlayer-migration
cd intlayer-migration
pnpm install
pnpm reset
pnpm migrate:dry
pnpm migrate:writeHand migrate-intlayer-report.md to an AI coding agent (or edit the flagged files yourself). The report includes the runtime module to paste over src/i18n.ts. In the locale control, call loadLocale(next) and then i18n.changeLanguage(next). loadLocale only registers the flat bundle.
pnpm i18n:sync
pnpm devpnpm i18n:sync runs extract first, which writes ui-languages.json. The bootstrap imports that file, so start the app only after extract. Do not edit strings.json, the flat locale files, or ui-languages.json by hand.
pnpm reset copies intlayer-pristine/ back over src/ and clears generated catalogs so you can start over.
Full walkthrough: examples/intlayer-migration/README.md.
Command
ai-i18n-tools migrate-intlayer [paths...] [--write] [--report <path>] [--content-glob <glob>] [--t-import <specifier>]Requires ui.stringsJson and ui.flatOutputDir in config (same as translate-ui). Does not call an LLM.
| Option | Meaning |
|---|---|
[paths...] | Files/dirs/globs to scan (default: ui.sourceRoots) |
--write | Seed the catalog and rewrite safe call sites (default: dry run) |
--report <path> | Report path (default: migrate-intlayer-report.md) |
--content-glob <glob> | Dictionary filename glob (default: **/*.content.ts) |
--t-import <specifier> | Import specifier for generated t() (default: relative ./i18n if src/i18n.ts exists, otherwise i18next) |
After --write, finish the manual-review sites from the report, delete the unused *.content.ts files and IntlayerProvider wrapper it lists, paste in the runtime bootstrap, and call i18n.changeLanguage from the locale control. Run extract then translate-ui (or sync) for source strings the report marks as new. extract also writes ui-languages.json, which the bootstrap imports. Do not edit strings.json, the flat locale files, or ui-languages.json by hand.
See also: CLI — UI strings, Wire i18next