3 stable releases
| 2.1.1 | Feb 28, 2026 |
|---|---|
| 2.0.2 | Feb 24, 2026 |
#171 in Internationalization (i18n)
2.5MB
473 lines
Tauri Plugin i18n (A simple wrapper around rust_i18n)
this project is a one fork of tauri-plugin-i18n
This plugin does not support macros from rust_i18n.
rust_i18n is only used for parsing the locales.

| Platform | Supported |
|---|---|
| Linux | ✓ |
| Windows | ✓ |
| macOS | ✓ |
| Android | Untested |
| iOS | Untested |
Install
This plugin requires a Rust version of at least 1.77.2
Install the Core plugin by adding the following to your Cargo.toml file:
src-tauri/Cargo.toml
# Point this to your fork's repository and branch/tag/rev
# Example using a GitHub repo:
[dependencies.tauri-plugin-i18n-vsk]
git = "https://github.com/VasakOS/tauri-plugin-i18n"
# Or use a local path if developing locally:
# path = "../path/to/your/fork/tauri-plugin-i18n"
The package can also be installed by using cargo:
cargo add tauri-plugin-i18n-vsk
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
Install the JavaScript bindings using your preferred package manager:
# Using bun
bun add @vasakgroup/tauri-plugin-i18n
# Using pnpm
pnpm add @vasakgroup/tauri-plugin-i18n
# Using npm
npm install @vasakgroup/tauri-plugin-i18n
# Using yarn
yarn add @vasakgroup/tauri-plugin-i18n
Locale file [rust_i18n implementation]
You can use _version key to specify the version (This version is the locale file version, not the rust-i18n version) of the locale file, and the default value is 1.
rust-i18n supports two style of config file, and those versions will always be keeping.
_version: 1- Split each locale into difference files, it is useful when your project wants to split to translate work._version: 2- Put all localized text into same file, it is easy to translate quickly by AI (e.g.: GitHub Copilot). When you write original text, just press Enter key, then AI will suggest you the translation text for other languages.
You can choose as you like.
Split Localized Texts into Difference Files
_version: 1
You can also split the each language into difference files, and you can choose (YAML, JSON, TOML), for example: en.json:
.
├── Cargo.lock
├── Cargo.toml
├── locales
│ ├── zh-CN.yml
│ ├── en.yml
└── src
│ └── main.rs
_version: 1
hello: 'Hello world'
mello: 'Mello world'
Or use JSON or TOML format, just rename the file to en.json or en.toml, and the content is like this:
{
"_version": 1,
"hello": "Hello world",
"mello": "Mello world"
}
hello = "Hello world"
mello = "Mello world"
All Localized Texts in One File
_version: 2
Make sure all localized files (containing the localized mappings) are located in the locales/ folder of the project root directory:
.
├── Cargo.lock
├── Cargo.toml
├── locales
│ ├── app.yml
│ ├── some-module.yml
└── src
│ └── main.rs
└── sub_app
│ └── locales
│ │ └── app.yml
│ └── src
│ │ └── main.rs
│ └── Cargo.toml
In the localized files, specify the localization keys and their corresponding values, for example, in app.yml:
_version: 2
hello:
en: Hello world
zh-CN: 你好世界
This is useful when you use GitHub Copilot, after you write a first translated text, then Copilot will auto generate other locale's translations for you.
Usage
First you need to register the core plugin with Tauri:
The init method takes two args:
- The location of the locales dir
- Default locale (eg: "en")
src-tauri/src/lib.rs
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_i18n::init(None))
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Afterwards all the plugin's APIs are available through the JavaScript guest bindings and also via tauri::AppHandle:
JS
import I18n from '@vasakgroup/tauri-plugin-i18n';
// Load translations
await I18n.getInstance().load();
// Example
//Get available locales
const locales = await I18n.getAvailableLocales();
console.log('Locales:', locales);
Rust
#[tauri::command]
fn get_locales(app: tauri::AppHandle)-> Vec<String> {
app.i18n().available_locales()
}
Updating the locale
JS
import I18n from '@vasakgroup/tauri-plugin-i18n';
// Example
// Set the locale
await I18n.setLocale('en');
Rust
#[tauri::command]
fn update_locale(app: tauri::AppHandle, locale: &str) {
app.i18n().set_locale(locale);
}
Using the locale
Note: The i18n class must be instantiated in order to translate in javascript.
JS
// In javascript, it uses the [data-i18n] attribute to remain framework agnostic
import I18n from '@vasakgroup/tauri-plugin-i18n';
// Load translations
await I18n.getInstance().load();
// Example
// Use a translation
<p data-i18n="hello"> </p>;
Rust
let translated: Option<&str> = app.i18n().translate("hello");
Call the destroy method in javascript when done to cleanup.
See the examples folder for a working app.
Companion package
Use package rust-i18n-autotranslate to autotranslate locales from a source locale.
Use .taurignore to prevent looping while running build.
This is because tauri tracks all files in the project unless explicitly ignored.
It can be used both at compile time and runtime
Compile time
//build.rs
use rust_i18n_autotranslate::{
TranslationAPI,
config::{Config, TranslationProvider},
};
fn main() {
//run translations
let target_locales = [
"es", "zh-CN", "zh-TW", "hi", "ar", "fr", "pt-BR", "de", "ru", "ja", "ko", "it", "tr",
"id", "vi",
];
let cfg = Config::new()
.locales_directory("./locales")
.source_lang("en")
.add_target_langs(target_locales.to_vec())
.use_cache(true)
.translation_provider(TranslationProvider::DEEPL)
.build();
TranslationAPI::translate(cfg).unwrap();
tauri_build::build();
}
Dependencies
~19–67MB
~1M SLoC