tauri-plugin-sys-locale 0.1.2

Tauri plugin to read the operating system's current locale/language
docs.rs failed to build tauri-plugin-sys-locale-0.1.2
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

tauri-plugin-sys-locale

A Tauri v2 plugin that reads the current operating system locale/language. Works cross-platform (Windows, macOS, Linux, and thanks to the sys-locale crate also iOS/Android), without needing any custom native Swift/Kotlin code.

1. Installation (Rust side)

In your Tauri app's Cargo.toml (src-tauri/Cargo.toml):

[dependencies]
tauri-plugin-sys-locale = tauri-plugin-sys-locale = "*"

In src-tauri/src/main.rs:

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_sys_locale::init())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

2. Enable the capability

In src-tauri/capabilities/default.json (or whichever capability file applies), add the permission:

{
  "identifier": "default",
  "windows": ["main"],
  "permissions": ["sys-locale:default"]
}

3. Installation (frontend side)

npm install tauri-plugin-sys-locale-api

4. Usage in the frontend

import { getLocale, getLocaleInfo } from "tauri-plugin-sys-locale-api";

const locale = await getLocale();
console.log(locale); // e.g. "de-DE"

const info = await getLocaleInfo();
console.log(info.language); // e.g. "de"

5. Using the functions directly from Rust (no JS/invoke needed)

The core logic lives in plain pub fns in src/api.rs (not tagged with #[tauri::command]), so you can call them from any Rust code — inside a Tauri command, a background task, setup(), etc. — without going through the frontend at all:

use tauri_plugin_sys_locale::api;

fn some_backend_logic() {
    match api::get_locale() {
        Ok(locale) => println!("System locale: {locale}"),
        Err(e) => eprintln!("Could not determine locale: {e}"),
    }

    // or with locale + language split apart:
    if let Ok(info) = api::get_locale_info() {
        println!("locale={}, language={}", info.locale, info.language);
    }
}

You can even call it directly inside main.rs, e.g. to set an initial window title or pick a translation file before the app finishes starting:

fn main() {
    let locale = tauri_plugin_sys_locale::api::get_locale()
        .unwrap_or_else(|_| "en-US".into());
    println!("Starting app with locale: {locale}");

    tauri::Builder::default()
        .plugin(tauri_plugin_sys_locale::init())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

The commands.rs module just wraps these same functions with #[tauri::command] so the frontend can reach them via invoke() — both paths call identical logic.

Why sys-locale instead of custom native code?

The sys-locale crate already wraps the platform-specific APIs:

  • Windows: GetUserDefaultLocaleName
  • macOS/iOS: NSLocale
  • Linux: environment variables (LANG, LC_ALL, ...)
  • Android: JNI call to Locale.getDefault()

That means you don't need a separate android/ or ios/ directory with Kotlin/Swift code, unlike many other Tauri plugins.

Building the JS bindings

npm install
npm run build

This compiles guest-js/index.ts into dist-js/index.js, dist-js/index.cjs, and the corresponding .d.ts type declarations.