Manage translations for plugins with hot-reload support and crowdsourced dictionaries.
I18n Plus is a powerful Obsidian internationalization (i18n) management plugin, and also a universal development framework for the plugin ecosystem.
For Users, it is an intuitive translation management tool that lets you easily translate/correct plugin translations. For Developers, it provides zero-dependency i18n adapters and automated migration tools.
Read the Whitepaper: For a deep dive into the philosophy, architecture, and future roadmap of Obsidian's third-party internationalization, please read the Whitepaper.
.json translation files for easy sharingt() calls with one commandi18n-plus in Obsidian Community Plugins.🌐 icon in the left sidebar, or use the command Open Dictionary Manager.zh or another language from the dropdown👁️ (View Content) button next to the pluginSave to apply changes immediatelySee the full Migration Guide for detailed integration instructions.
Copy the adapter to your plugin:
cp templates/adapter.ts your-plugin/src/lang/i18n.ts
Initialize in main.ts:
import { initI18n } from './lang/i18n';
export default class MyPlugin extends Plugin {
i18n: I18nAdapter;
t: (key: string, params?: any) => string;
async onload() {
this.i18n = initI18n(this);
this.t = this.i18n.t.bind(this.i18n);
}
}
Use translations:
new Notice(this.t("Hello, {name}!", { name: "World" }));
Run the codemod to automatically replace hardcoded strings:
# Install jscodeshift
npm install -g jscodeshift
# Run codemod on your plugin
npx jscodeshift -t scripts/i18n-codemod.cjs your-plugin/src/ --parser=ts
# Extract keys to generate en.ts
node scripts/extract-keys.cjs your-plugin/src
When t("key") is called, the adapter searches in this order:
This means:
┌─────────────────────────────────────────────────────────┐
│ Your Plugin │
│ ┌─────────────────────────────────────────────────┐ │
│ │ adapter.ts (self-contained, ~150 lines) │ │
│ │ ├── BUILTIN_LOCALES: { en, zh, ... } │ │
│ │ └── _externalDictionaries: { de, fr, ... } │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
▲
│ (optional)
▼
┌─────────────────────────────────────────────────────────┐
│ I18n Plus Plugin (optional) │
│ ├── Dictionary Manager UI │
│ ├── Global Locale Sync │
│ └── External .json Import/Export │
└─────────────────────────────────────────────────────────┘
| Script | Description |
|---|---|
i18n-codemod.cjs |
Transform hardcoded strings to t() calls |
extract-keys.cjs |
Extract all keys and generate en.ts |
inject-i18n.cjs |
Auto-inject adapter into main.ts |
generate-report.cjs |
Generate migration report |
| Command | Description |
|---|---|
npm run dev |
Start development mode with hot reload |
npm run build |
Build the plugin (output to project root) |
npm run deploy |
Build and copy to Obsidian test vault |
npm run lint |
Run ESLint checks |
The deploy command automatically copies build artifacts to your local Obsidian vault for testing.
Setup:
Create deploy.config.local.json in project root:
{
"targetDir": "C:\\path\\to\\your\\.obsidian\\plugins\\i18n-plus"
}
Run:
npm run deploy
Note:
deploy.config.local.jsonis gitignored to keep your local paths private.
templates/
└── adapter.ts # Copy this to your plugin
scripts/
├── i18n-codemod.cjs # String replacement codemod
├── extract-keys.cjs # Key extraction script
└── inject-i18n.cjs # Auto-injection script
examples/
└── auto-migrate-workflow.yml # GitHub Action template
docs/
├── README.zh-CN.md # Chinese documentation
└── I18N_MIGRATION_GUIDE.zh-CN.md # Migration guide
This project was built using Vibe Coding. While I have done my best to ensure the reliability of the code, please do not use this project if you are uncomfortable with this approach.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE for details.