Configuration
Lingo.dev uses two key configuration files: i18n.json
and i18n.lock
. These files control how Lingo.dev handles your translations and tracks changes.
i18n.json
This file defines your translation setup and file structure. It specifies the source and target languages, as well as the translation buckets (more on that later).
Here's an example i18n.json
file:
{
"version": 1.1,
"locale": {
"source": "en",
"targets": ["es"]
},
"buckets": {
"json": {
"include": ["locales/[locale].json"]
},
"xcode": {
"include": ["xcode/Localizable.xcstrings"]
},
"android": {
"include": ["android/[locale].xml"]
},
"yaml": {
"include": ["yaml/[locale].yml"]
},
"yaml-root-key": {
"include": ["yaml-root-key/[locale].yml"]
},
"markdown": {
"include": ["markdown/[locale].md"]
}
}
}
Now, let's break down the different sections of this file.
Locale
source
: Your primary language for content creation.targets
: Languages you want to translate into.
Pro tip: there's a handy command to list supported locales:
replexica show sources # List source locales
replexica show targets # List target locales
# Check if a specific [target] locale is supported
replexica show targets | grep fr
Buckets
Buckets define where Lingo.dev finds and saves translations. Each bucket specifies a file type and includes an include
array for file patterns to translate. Optionally, you can add an exclude
array to ignore certain files.
Simple example:
{
"buckets": {
"json": {
"include": ["locales/[locale].json"],
"exclude": ["locales/[locale]/skip.json"]
}
}
}
For more advanced cases, you can customize how locale codes appear in filenames. You can specify paths in two ways:
- Simple string pattern (uses default delimiter):
"include": ["locales/[locale].json"]
- Object with custom delimiter (overrides default):
"include": [
{
"path": "locales/[locale].json",
"delimiter": "_" // Use underscore instead of default delimiter
}
]
The delimiter
can be:
-
(dash, e.g.,en-US
)_
(underscore, e.g.,en_US
)
When not specified in the path object (or set to null
), the delimiter defaults to the one used in your source
and targets
fields. For example:
{
"locale": {
"source": "en-US", // Uses dash as default delimiter
"targets": ["es-ES", "fr-FR"]
},
"buckets": {
"json": {
"include": [
"locales/[locale].json", // Will use dash: en-US.json, es-ES.json
{
"path": "other/[locale].json",
"delimiter": "_" // Will use underscore: en_US.json, es_ES.json
}
]
}
}
}
This is particularly useful when different files in your project use different locale code formats (e.g., some files using en-US.json
while others use en_US.json
).
JSON (
json
)- Include pattern:
locales/[locale].json
- Requires
[locale]
: Yes - Creates separate JSON files for each language.
- Include pattern:
Xcode (
xcode
)- Include pattern:
xcode/Localizable.xcstrings
- Requires
[locale]
: No - Uses a single file for all languages in Xcode's format.
- Include pattern:
Android (
android
)- Include pattern:
android/[locale].xml
- Requires
[locale]
: Yes - Creates separate XML files for each language, following Android's structure.
- Include pattern:
YAML (
yaml
)- Include pattern:
yaml/[locale].yml
- Requires
[locale]
: Yes - Creates separate YAML files for each language.
- Include pattern:
YAML with root key (
yaml-root-key
)- Include pattern:
yaml-root-key/[locale].yml
- Requires
[locale]
: Yes - Creates YAML files with root keys, commonly used in Ruby on Rails. The key difference from the regular YAML format is that it wraps all translations under a root key (e.g.,
en:
,es:
) that matches the locale.
- Include pattern:
Markdown (
markdown
)- Include pattern:
markdown/[locale].md
- Requires
[locale]
: Yes - Creates separate Markdown files for each language.
- Include pattern:
The [locale]
placeholder is crucial for formats that require separate files per language. It's dynamically replaced with the actual language code (e.g., "en", "es") during processing.
TIP
You can use multiple include patterns and exclude specific files. For example:
"markdown": {
"include": [
"docs/[locale]/*.md",
"blog/[locale]/*.md"
],
"exclude": [
"docs/[locale]/internal-*.md"
]
}
This will translate all Markdown files in docs
and blog
directories, except for those starting with internal-
in the docs
directory.
i18n.lock
The i18n.lock
file is a key element behind Lingo.dev's efficient translation process. It stores checksums of the source content (in your repo, so you're in full control), enabling Lingo.dev to detect changes and only translate what's necessary.
version: 1
checksums:
a07974ea09011daa56f9df706530e442:
key: f8692d39317193acf0e2e47172703c46
Key aspects of i18n.lock
:
Purpose:
- Tracks the state of source content;
- Enables efficient updates by identifying changed content;
- Ensures consistency across your translation workflow.
Usage:
- Automatically generated and updated by Lingo.dev;
- Should be committed to your version control system;
- Helps in CI/CD pipelines to determine necessary translation updates.
Benefits:
- Reduces unnecessary translation requests;
- Speeds up the translation process in subsequent runs;
- Provides a clear history of content changes.
By leveraging both i18n.json
and i18n.lock
, Lingo.dev offers a robust, efficient, and version-controlled approach to managing your project's localization infrastructure. The new bucket configuration in i18n.json
allows for more granular control over which files are included in or excluded from the translation process, giving you greater flexibility in managing your localization workflow.