An IntelliJ IDEA plugin that extracts hard-coded strings (Chinese, Japanese, Korean, English, and more) from Vue / React projects and replaces them with i18n calls in one click.
简体中文 | English
- Multi-framework support: auto-detects the project framework and uses the matching i18n syntax accordingly
- Multi-language extraction: extracts Chinese, Japanese, Korean, English, French, Russian, German, Spanish, Italian and Portuguese — the target languages are configurable in Settings
- Smart extraction: scans template text, attribute values, TS string literals, string concatenation and template literals
- Context-aware: decides whether a string is user-facing copy based on its role in the syntax tree (text node, attribute, JS string, etc.), not just raw characters
- Auto-injection: automatically adds
importstatements and hook declarations (useI18nfor Vue /useTranslationfor React) - Idempotent & safe: skips already-internationalized text and never re-extracts
- Batch processing: supports both single-file extraction and project-wide batch extraction
- JSON export: formats extraction results as JSON and copies them to the clipboard with one click
- Undo support: all edits are wrapped in
WriteCommandAction, so Ctrl+Z works fully - Template interpolation: supports
${variable}template-literal interpolation and converts it into the i18n placeholder format - Merge suggestions: automatically detects common prefixes/suffixes and digit placeholders to suggest merging similar strings
Framework support status: Vue (
vue-i18n) and React (react-i18next) are the primary, fully-tested targets. Other frameworks (e.g. Angular /ngx-translate, Svelte, i18next standalone) are experimental — the code paths exist but are not covered by the test suite, are not guaranteed to produce correct output, and may change without notice. If you rely on a non-Vue/React framework in production, validate the generated code before applying it.
| Type | Extension |
|---|---|
| Vue single-file components | .vue |
| React components | .tsx |
| TypeScript | .ts |
| Language | Code | Notes |
|---|---|---|
| Chinese | zh |
CJK ideographs, enabled by default |
| Japanese | ja |
Hiragana + Katakana |
| Korean | ko |
Hangul syllables |
| English | en |
Sentence/phrase heuristic (Approach A) |
| French | fr |
Accented characters |
| Russian | ru |
Cyrillic |
| German | de |
Umlauts + ß |
| Spanish | es |
ñ + accented vowels |
| Italian | it |
Accented vowels |
| Portuguese | pt |
Tilde vowels |
Note: Latin-script languages (English, French, German, Spanish, Italian, Portuguese) overlap on pure-ASCII text. Each is detected deterministically via its distinctive characters; pure-ASCII text is only picked up by the English heuristic. This is a known and intentional trade-off.
Open Settings → Plugins → Marketplace in your IDE, search I18n-Extractor and install it.
- Download the latest
.zipfrom Releases - Open
Settings → Plugins → ⚙ → Install Plugin from Disk...in your IDE - Select the downloaded zip and restart the IDE
- Open a
.vue/.tsx/.tsfile - Right-click in the editor → I18n Extraction
- Preview the extracted JSON, confirm with OK
- Code is automatically replaced with
$t()calls, and the JSON is sent to the configured output (clipboard / file / ask)
- Open the
Refactormenu → Project I18n Extraction - The plugin scans matching files based on the
includeconfiguration oftsconfig.json - Preview all extractions, confirm and apply the batch replacement
Open Settings → Tools → I18n Extractor:
| Option | Description | Default |
|---|---|---|
| Target languages | Which languages to extract (multi-select) | Chinese only |
| Output destination | Clipboard / Write to file / Ask every time | Ask every time |
| Min string length | Strings shorter than this are not extracted | 1 |
| Merge affix threshold | Combined common prefix/suffix chars required to generate a merge suggestion | 2 |
| Exclude directories | Directory names skipped during scanning (comma-separated) | node_modules, .git, dist, ... |
| Custom translation dirs | Extra translation-resource directory names (comma-separated) | (empty) |
| Vue placeholder prefix | Prefix for Vue named placeholders (e.g. N → {N0}; must not be empty) |
N |
The output destination controls behaviour after extraction: choosing Clipboard or Write to file skips the dialog prompt and outputs directly; choosing Ask every time shows the options in the dialog (backward compatible).
<!-- Before -->
<template>
<div>你好,世界</div>
<button type="primary" @click="handleSubmit">确定</button>
</template>
<!-- After -->
<template>
<div>{{ $t('你好,世界') }}</div>
<button type="primary" @click="handleSubmit">{{ $t('确定') }}</button>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
const { t: $t } = useI18n();
</script>// Before
export default function App() {
return <div title="提示信息">你好</div>
}
// After
import { useTranslation } from 'react-i18next';
export default function App() {
const { t: $t } = useTranslation();
return <div title={$t('提示信息')}>{ $t(`你好`) }</div>
}// Before
const msg = `欢迎,${userName}!`
// After (Vue)
const msg = $t('欢迎,{0}!', { "0": userName })
// After (React)
const msg = $t('欢迎,{{0}}!', { "0": userName })- Plain text nodes in Vue templates:
<div>中文</div> - Vue attribute values (including strings inside dynamic directive bindings)
- React JSX text nodes and attribute values
- JS/TS string literals:
'中文',"中文",`中文` - String concatenation:
"你好" + name - Template literals:
`欢迎,${name}` - Explicit string literals inside directives such as
:title="'中文'"
- Already-internationalized text:
$t('xxx'),t('xxx') - Text inside comments
- Text inside
<style>tags - TypeScript enum member values (not supported at runtime, would raise TS18033)
- Pure English/symbol/pre-existing-code strings that are
$tcalls or identifiers Enum['中文']indexed access- Strings shorter than the configured minimum length
src/
├── main/kotlin/com/pan/extractor/
│ ├── AllI18nExtractorAction.kt # Project-level batch extraction action
│ ├── I18nExtractorAction.kt # Single-file extraction action
│ ├── I18nProcessor.kt # Core extraction & replacement logic
│ ├── LanguageExtractor.kt # Pluggable multi-language extractors (zh/ja/ko/en/fr/ru/de/es/it/pt)
│ ├── I18nSettings.kt # Global settings & persistence
│ ├── I18nSettingsConfigurable.kt # Settings panel (Settings → Tools → I18n Extractor)
│ ├── CommonPrefixSuffixFactorizer.kt # Merge-suggestion factorizer (prefix/suffix & digit groups)
│ ├── MergeApplier.kt # Applies merge suggestions to code & resource files
│ ├── ExtractedStringsDialog.kt # Result preview dialog
│ └── Util.kt # Utilities (framework detection, write-back, etc.)
├── main/resources/META-INF/
│ └── plugin.xml # Plugin configuration
└── test/kotlin/com/pan/extractor/
├── I18nProcessorTest.kt # JS/TS general logic tests
├── VueI18nProcessorTest.kt # Vue-specific tests
├── ReactI18nProcessorTest.kt # React-specific tests
├── LanguageExtractorSettingsTest.kt# Multi-language & settings tests
└── ... # Merge, write-back, factorizer and regression tests
- JDK 21+
- Gradle 9.0+
./gradlew build./gradlew test./gradlew runIdeIssues and Pull Requests are welcome!
MIT