Migrating an existing project
Four things go wrong in a migration: partial imports, encoding damage, lost history and comments, and drift between the old source and the new one during the cutover. Sequence the work so all four stay visible.
Check the key cap
Section titled “Check the key cap”Comvi caps translation keys per organization and enforces the cap on every key created. The
import validator warns before the commit with the estimated new key count, current usage
and the limit. Count your source keys first; if the number is above the plan’s limit, cut
scope or upgrade before you import. Going over the key, member or
project limit puts the organization into read-only, where every write fails with
403 READ_ONLY_MODE, so leave headroom. Keys, projects, members and MT credits are all
capped per plan, and languages are not; read the current limits.
Inventory
Section titled “Inventory”| Metric | Why it matters |
|---|---|
| Key count | Checked against the key limit before anything else |
| Keys per namespace or file | Drives the namespace layout |
| File formats | Comvi imports JSON files and ZIP archives of JSON only. i18next-shaped JSON imports, and non-ICU plural syntax is converted; anything else needs converting first |
| Placeholder format | {{name}} and %s are converted or need converting to ICU |
| Scripts in use | Arabic, Hebrew and CJK content is where encoding damage shows |
Decide the cutover model too. A hard cutover freezes the old system and Comvi takes over; it needs a freeze window. Writing to both systems for a while is lower risk and costs a reconciliation pass at the end. A dataset that fits one import batch usually takes a hard cutover of a day or two.
Before touching the full dataset, take the smallest namespace or the top 200 keys, one source language plus one target, through the whole import. Check keys, values, statuses, ICU placeholders, special characters and line breaks against the source. Budget a day.
Set up the target project
Section titled “Set up the target project”-
Create the project with your source language (Projects). It cannot be changed after creation.
-
Add the target languages (Languages). Codes are canonical BCP-47:
pt-BR,zh-Hans,en-US. -
Create the namespaces matching the current file layout. Do not restructure while migrating; a namespace with keys cannot be deleted.
-
Import the glossary, so the glossary check has something to say from the first review. See Glossaries.
-
Import the translation memory as TMX if the old system exports it, so fuzzy matches are live afterwards. See Translation memory.
Import
Section titled “Import”-
Export from the old system into one JSON file per language per namespace, and normalize:
{{name}}to{name},%sto{arg1}, stray braces escaped as'{', UTF-8 only (file -I *.json). -
Lay the archive out so detection works. The wizard reads the namespace and locale from each path:
import.zip/├── common/│ ├── en.json│ ├── de.json│ └── …└── checkout/├── en.json└── …The mapping table on the import screen lets you set namespace and locale per file and create a missing namespace before committing. Limits per batch: 50 files, 10 MB each, 500 entries per ZIP, 100,000 keys, and a session expires after one hour.
-
Read the validation report. Uploading validates without writing: per file, the detected format, conflicts with existing content, and whether it parsed. The summary counts files, total keys and unique keys, and flags a key-limit overrun.
-
Resolve conflicts. A conflict is a key and locale that already holds a different value. Choose Keep existing or Use imported per conflict or in bulk, and set the Unresolved Conflict Policy for the rest. A first pass into an empty project has nothing to conflict with.
-
Commit, then check what landed. Every non-empty value lands as
Translatedwith the importing user as reviewer; empty values land asNot Translated. To keep a review step for untrusted content, select the imported rows on the Translations page and use Status → Mark as Needs Review. -
Import the remaining languages three to five at a time, so each job stays short and an error stays attributable.
See Import & export for the full wizard reference.
Reconcile
Section titled “Reconcile”GET /v1/projects/:id/locales/stats returns per-locale totals and
percentages, and the Languages page shows the same numbers.
- Total keys should equal the inventory. A shortfall means a file failed to parse or was left unmapped.
- Translated count per locale should match what the old system called approved.
- Placeholder integrity. For every source
{foo}, each target should contain{foo}. Comvi does not verify this on save or import. - Encoding. Search for
?runs and sequences likeéand’.
Fix the gaps with a second, targeted import.
Cut over
Section titled “Cut over”-
Point staging at the new endpoint. Enable Settings → Content Deploy, copy the endpoint URL, and pass it to the fetch loader as
cdnUrlin staging. -
Run the app’s QA suite against staging. Watch plurals, right-to-left languages, and long-string languages such as German and Russian.
-
Swap production. Change the production
cdnUrl, deploy, and keep the old system readable but not writable as fallback. -
Watch for missing keys for a day. A key that did not arrive shows up as a missing-key warning from the i18n library at runtime.
-
Decommission. Revoke the old system’s credentials, archive the old export files, and send the translation team the editor URL and Your first project.
History and comments
Section titled “History and comments”Comvi imports values, not the old system’s change history or comments, and neither can be back-dated. Either accept the break, with Comvi’s history starting at the import, or export the old history as CSV and keep it next to the repository. Move any comment a translator needs into the key’s Internal notes (not sent to MT), or into AI translation context (sent to MT) if a provider should see it too.
Time budget
Section titled “Time budget”| Phase | Duration |
|---|---|
| Inventory and pilot | 1 to 2 days |
| Normalization and validation | 1 to 2 days |
| Full import and reconciliation | 1 day |
| Staging QA | 1 to 2 days |
| Cutover and monitoring | 1 day |
For roughly 3,000 keys across 10 languages, five to eight days in total. The longest parts are outside Comvi: converting placeholder syntax and running your own QA suite. Freeze writes on both systems for the cutover window, and check whether the old system’s “translated” means per-language approval before deciding what the import should write.