This plugin enables your inlang project to read and write [i18next](https://inlang.com/m/kl95463j) translation files.
This plugin enables your inlang project to read and write i18next translation files.
If you're using i18next for internationalization, this plugin lets you:
- Manage translations with Fink – a translation editor for collaborating with translators
- Get inline previews with Sherlock – a VS Code extension that shows translations directly in your code
- Lint translations with inlang CLI – catch missing translations, unused keys, and other issues
- Automate workflows with the inlang SDK – build custom tooling around your translations
The plugin reads and writes i18next JSON files, preserving your existing file structure (nested or flat keys, namespaces, plurals). It also tells Sherlock how to detect t() function calls in your code so you see inline translation previews.
| Feature | Status | Notes |
|---------|--------|-------|
| Basic key-value pairs | ✅ Supported | Fully working |
| Nested keys | ✅ Supported | Auto-detects flat vs nested structure |
| Variable interpolation | ✅ Supported | {{variable}} with customizable patterns |
| Unescaped interpolation | ✅ Supported | {{- variable}} syntax |
| Formatting | ✅ Supported | Simple format functions like {{value, uppercase}} |
| Formatting with options | ❌ Not supported | {{value, format, option}} will throw an error on export |
| Plurals | ✅ Supported | All forms: _zero, _one, _two, _few, _many, _other |
| Context | ⚠️ Partial | Basic context suffix detection (e.g., key_male) |
| Namespaces | ✅ Supported | Single and multiple namespace configurations |
| Nesting ($t()) | ⚠️ Read-only | Recognized but cannot be translated inline |
| Objects/Arrays as values | ✅ Supported | Preserved during roundtrip |
- i18next v21+: Full support (uses JSON v4 plural format with _one, _other, etc.)
- i18next v11-v20: Full support
- i18next v1-v10: Limited support (older plural format _plural may need migration)
- Add this to the modules in your project.inlang/settings.json
- Change the baseLocale if needed
- Include existing locales in the locales array
``diff`
{
"baseLocale": "en",
"locales": ["en", "de"],
"modules": [
+ "https://cdn.jsdelivr.net/npm/@inlang/plugin-i18next@latest/dist/index.js"
],
+ "plugin.inlang.i18next": {
+ "pathPattern": "./resources/{locale}.json"
+ }
}
The plugin offers further configuration options that can be passed as arguments. The following settings exist:
`typescript`
type PluginSettings = {
pathPattern: string | { [key: string]: string }
variableReferencePattern?: [string] | [string, string]
sourceLanguageFilePath?: string
}
To use our plugin, you need to provide a path to the directory where your language-specific files are stored. Use the dynamic path syntax {locale} to specify the language name.
`json`
"plugin.inlang.i18next": {
"pathPattern": "./resources/{locale}.json"
}
`json`
"plugin.inlang.i18next": {
"pathPattern": {
"common": "./resources/{locale}/common.json",
"vital": "./resources/{locale}/vital.json"
}
}
key (prefix): is prefixing the key with a colonvalues (path): is the path to the namespace resources
This defines the pattern for variable references. The default is how i18next suggests using placeholders.
default:
`json`
"plugin.inlang.i18next": {
"variableReferencePattern": ["{{", "}}"]
}
This setting is optional and should only be used if the file name of your sourcelocale does not match your pathPattern structure. For example, if your sourcelocale is en but your sourceLanguage file is called main.json, you can use this setting to specify the path to the sourceLanguage file. We recommend renaming the file to en.json and not using this setting.
`json`
"plugin.inlang.i18next": {
"sourceLanguageFilePath": "./resources/main.json"
}
`json`
"plugin.inlang.i18next": {
"sourceLanguageFilePath": {
"common": "./resources/main/common.json",
"vital": "./resources/main/vital.json"
}
}
t("key")
With namespaces:
t("namespace:key") or t("key", { ns: "namespace" })
To learn about namespaces and how to use translation functions in your code, refer to the i18next documentation. The plugin can parse the code and provide the VS Code extension (Sherlock) with this information.
The source language file determines the structure for all other locale files:
- Key ordering: Messages are sorted in the order they appear in the source language file
- Nesting vs flat: Detected per-file from the source language. If your en.json uses nested keys, all other locales will use nested keys too
- New keys: When you add translations for other locales, they follow the source file's structure
If your source language (en.json) looks like this:`json`
{
"common": {
"save": "Save",
"cancel": "Cancel"
}
}
Then your target language (de.json) will be written in the same nested structure:`json`
{
"common": {
"save": "Speichern",
"cancel": "Abbrechen"
}
}
Plural forms are automatically generated with i18next suffixes:
| Input | Generated keys |
|-------|----------------|
| Message with count variable | key_one, key_other (minimum) |key_zero
| Full plural support | , key_one, key_two, key_few, key_many, key_other |
The plugin uses the CLDR plural rules for each locale to determine which plural forms are needed.
The following i18next features are not supported by this plugin:
| Feature | Limitation |
|---------|------------|
| Formatting with options | {{value, number(minimumFractionDigits: 2)}} will throw "Not implemented" error on export |$t(key)
| Inline nesting | references are read but cannot be edited or translated inline |t
| Postprocessors | Runtime-only feature, not applicable to static translation files |
| Context + Plural combinations | Complex variants may not roundtrip correctly |
| Template literal strings | Only single and double quoted strings are parsed in code |
| Custom function aliases | Only standard t() function calls are detected by Sherlock |
Cause: You're using formatting functions with options like {{value, number, minimumFractionDigits: 2}}.
Solution: Simplify to basic formatting {{value, number}} or use plain variables {{value}}. Complex formatting options are not supported.
Cause: The source language file structure doesn't match what the plugin expects.
Solution:
1. Ensure your source language file (e.g., en.json) is valid JSON
2. Check that the file structure is consistent (all nested or all flat)
3. The source language file is the "source of truth" for key ordering
Cause: Using old i18next plural format or mismatched suffixes.
Solution:
- Use i18next v4 JSON format with suffixes: _zero, _one, _two, _few, _many, _otherkey_plural
- Old format () is not supported - migrate to the new formatcount
- Ensure the variable is used in your translation
Cause: Non-standard function names or unsupported file types.
Solution:
- Use the standard t("key") function call syntax.ts
- Supported file types: , .js, .tsx, .jsx, .sveltet("namespace:key")
- For namespaces, use or t("key", { ns: "namespace" })
Cause: Keys like "my.key.name" are ambiguous - could be nested or a literal dot in the key.
Solution: The plugin handles this automatically using unicode escaping. Keys with literal dots are preserved correctly during roundtrip.
Cause: Target files don't exist or path pattern is incorrect.
Solution:
1. Verify your pathPattern matches your file structure{locale}
2. Check that the placeholder is in the correct positionlocales
3. Directories are created automatically, but the locale must be in your array
Run the following commands in your terminal (node and npm must be installed):
1. npm installnpm run dev
2.
npm run dev will start the development environment which automatically compiles the src/index.ts files to JavaScript (dist/index.js), runs tests defined in *.test.ts` files and watches changes.