A internationalization (i18n) parser for extracting and managing translations in TypeScript and React applications. This tool automatically identifies text strings in your codebase and generates appropriate translation keys according to your configuration.
- 🔍 Automatically identifies translatable content in:
- JSX text nodes
- String literals
- Component properties
- JSX fragments (
<></>) - Object properties
- Variable assignments
- 🔄 Generates hierarchical translation keys based on component depth and type
- ⚙️ Highly configurable through JSON configuration files
- 🛠️ Preserves original code formatting
- 📦 Outputs transformed code with translation function calls
- 📝 Creates a translations JSON file ready for localization
import { I18nParser } from 'typescript-i18n-parser';
import path from 'path';
import fs from 'fs-extra';
// Create a parser instance with default config
const parser = new I18nParser();
// Parse a file and get the transformed code + translations
const result = parser.parseFile(
'src/components/MyComponent.tsx',
'dist/components/MyComponent.tsx'
);
// Save the translations to a JSON file
parser.saveTranslations('translations/en.json');import { I18nParser } from 'typescript-i18n-parser';
import glob from 'glob';
import path from 'path';
const parser = new I18nParser('./i18n-config.json');
const srcDir = './src';
const distDir = './dist';
// Process all TypeScript/React files
const files = glob.sync(`${srcDir}/**/*.{ts,tsx}`);
files.forEach(file => {
const relativePath = path.relative(srcDir, file);
const outputPath = path.join(distDir, relativePath);
parser.parseFile(file, outputPath);
});
// Save all collected translations
parser.saveTranslations('./translations/en.json');Create a i18n-config.json file in your project root:
{
"parsing": {
"components": {
"Button": {
"props": ["label", "tooltip"]
},
"TextField": {
"props": ["placeholder", "helperText"]
},
"Title": {
"textChild": true
}
},
"ignoreProps": ["className", "style", "id", "key", "data-testid"]
},
"nodeTypeMap": {
"h1": "Title",
"h2": "Title",
"h3": "Title",
"h4": "Title",
"h5": "Title",
"h6": "Title",
"p": "Subtitle",
"div": "Text",
"span": "Text",
"Fragment": "Text"
}
}Specifies which components and their props should be processed for translations:
props: Array of property names to be translatedtextChild: Boolean indicating whether direct text children should be translated
Array of property names that should be ignored during translation.
Maps HTML elements to node types which affect the generated translation keys.
The parser traverses your code's Abstract Syntax Tree (AST) and:
- Identifies translatable strings and text nodes
- Generates appropriate translation keys based on component hierarchy and node type
- Replaces original text with translation function calls (
t("translationKey")) - Collects all translations in a dictionary for export
Translation keys are generated based on:
- Depth Category: Based on component nesting depth:
Section- Components at depth ≤ 3Part- Components at depth ≤ 5Area- Components at depth > 5
- Component Type: Determined by the component or HTML element:
- Based on the
nodeTypeMapconfiguration - Default values include "Title", "Subtitle", "Text", etc.
- Occurrence Counter: A number that increments each time the same component/type appears
Example key format: SectionTitle1, AreaButtonLabel2, PartText3
<div>
<h1>Welcome to our app</h1>
<Button label="Sign In" />
</div><div>
{t("SectionTitle1")}
<Button label={t("AreaButtonLabel1")} />
</div>{
"SectionTitle1": "Welcome to our app",
"AreaButtonLabel1": "Sign In"
}