Translation files are code. They should be versioned, reviewed, and maintained with the same care as any other source file.
But translation files have unique characteristics that can make Git workflows tricky. They’re often edited outside of IDEs, may be modified by non-developers, and changes can span many files simultaneously.
This guide covers practical strategies for managing i18n files in Git-based workflows.
File Organization
How you organize translation files affects how well they work with Git.
Flat structure
/locales
en.json
es.json
fr.json
de.json
Simple and works for smaller projects. Merges involve entire files, which can be problematic if they’re large.
Nested by feature/module
/locales
/common
en.json
es.json
/auth
en.json
es.json
/dashboard
en.json
es.json
Smaller files mean smaller conflicts. Features can be developed and merged independently.
Language-first vs feature-first
Language-first (shown above): Each language is one file or one directory. Good for translators working on a single language.
Feature-first:
/features
/auth
/i18n
en.json
es.json
/dashboard
/i18n
en.json
es.json
Keeps translations close to the code they support. Good for developer-led workflows.
The right choice depends on who edits translations and how your codebase is organized.
Branching Strategies
Feature branches include translations
The simplest approach: feature branches include translation changes alongside code.
# Working on a feature branch
git checkout -b feature/user-profile
# Add code with new translation keys
# Add the translations themselves
# Commit together
git add src/components/Profile.tsx locales/en.json locales/es.json
git commit -m "Add user profile page with translations"
Pros: Changes are atomic; translations ship with features Cons: Translations may conflict if multiple features touch the same files
Separate translation branches
For larger projects, separate branches for translation work:
# Feature branch has placeholder keys
git checkout -b feature/user-profile
# Add code with keys
git commit -m "Add user profile page"
# Translation branch adds the actual strings
git checkout -b translations/user-profile
# Add translations
git commit -m "Add translations for user profile"
# Merge both
git checkout main
git merge feature/user-profile
git merge translations/user-profile
Pros: Translators can work independently; clear separation of concerns Cons: More complex workflow; potential for orphaned keys
Release-based translation updates
Translations updated at release boundaries:
# During sprint, features add placeholder keys
# Before release, translation branch catches up
git checkout -b release/2.1-translations
langctl pull # or manually update files
git commit -m "Update translations for release 2.1"
git checkout main
git merge release/2.1-translations
Pros: Clean release process; batch translation work Cons: Translations lag behind code; harder to test during development
Handling Merge Conflicts
Translation files in JSON or YAML format are prone to merge conflicts, especially in the common pattern where keys are alphabetized.
Prevention
- Smaller files: Split translations by feature or module
- Consistent formatting: Use tools to maintain consistent key order
- Frequent merges: Don’t let branches diverge too far
Resolution
When conflicts occur:
<<<<<<< HEAD
"welcome.title": "Welcome back",
"welcome.subtitle": "We missed you"
=======
"welcome.title": "Hello again",
"welcome.new_feature": "Try our new feature"
>>>>>>> feature/new-feature
Usually the resolution is to keep both changes:
"welcome.title": "Welcome back",
"welcome.subtitle": "We missed you",
"welcome.new_feature": "Try our new feature"
For conflicting edits to the same key, you’ll need to decide which version is correct.
Tooling help
Some CLI tools can help detect and resolve translation conflicts:
# After resolving conflicts
langctl validate # Check for duplicate keys, invalid format
# Some tools offer smart merge
langctl merge --auto # Attempts to combine changes automatically
Code Review for Translations
Translation changes should go through code review like any other change.
What to review
- Key naming: Are keys consistent with existing conventions?
- Missing languages: Do all supported languages have the new keys?
- Placeholders: Are variables and interpolations correct?
- Formatting: Does the file maintain consistent structure?
Review checklist
## Translation Review
- [ ] Key names follow project conventions
- [ ] All supported languages updated
- [ ] No hardcoded text in source files
- [ ] Variable placeholders match between languages
- [ ] File formatting is consistent
Automated checks
In CI/CD, validate translation files:
- name: Validate translations
run: |
langctl validate
langctl status --fail-on-missing
This catches missing translations and format errors before merge.
Maintaining Translation History
Git history for translations serves several purposes:
- Audit trail: Who changed what, when
- Rollback capability: Revert problematic changes
- Understanding context: Why was this text changed?
Commit messages
Good commit messages for translations:
Add translations for checkout flow
- New keys: checkout.title, checkout.submit, checkout.cancel
- Updated: cart.empty_message (improved clarity)
- Languages: en, es, fr
Bad commit messages:
Update translations
Keeping history clean
Avoid commits that only fix formatting or key ordering. If tools reorganize your translation files, commit those changes separately:
git commit -m "Reformat translation files (no content changes)"
This keeps content changes separate from formatting noise.
Working with External Translators
When non-developers contribute translations, Git workflows need adaptation.
Option 1: Managed access
Give translators Git access (or access through a platform like GitHub):
- Create branches for translation work
- Submit pull requests for review
- Use review process for quality control
Works if translators are comfortable with Git basics.
Option 2: Sync through tooling
Use a translation platform that syncs with Git:
# Developer workflow
langctl push # Send keys to platform
# Translator works in web interface
# Developer pulls back
langctl pull
git add locales/
git commit -m "Update translations from platform"
The translation platform handles the translator interface; Git handles versioning.
Option 3: Export/import cycle
For occasional translator involvement:
# Export for translators
langctl export --format xlsx --output translations-for-review.xlsx
# Translators edit spreadsheet
# Import when done
langctl import --file translations-reviewed.xlsx
git add locales/
git commit -m "Import reviewed translations"
Less elegant but works with any translator workflow.
Summary: Best Practices
-
Organize files to minimize merge conflicts (smaller files, logical grouping)
-
Include translations in feature branches for atomic changes
-
Review translation changes like code changes
-
Automate validation in CI/CD to catch errors early
-
Write meaningful commit messages that explain what changed
-
Use tooling to help with sync, validation, and conflict resolution
-
Plan for non-developer contributors if translators will be involved
Good Git hygiene for translations makes localization sustainable as projects grow.
Next steps: Automating i18n in CI/CD Pipelines covers how to integrate translation validation into your build process.